NOIP 提高組 初賽 四、閱讀程序寫結果 習題集(三)NOIP2004-NOIP2005

NOIP 提高組 初賽 四、閱讀程序寫結果 習題集(三)NOIP2004-NOIP2005

1.第十屆(NOIP2004)

問題(原文是pascal,按題意,本人改寫成C,C++版本):

1.

//2004.4.1
#include <stdio.h>

int main(){
    int u[4];
    int a,b,c,x,y,z;
    scanf("%d %d %d %d",&u[0],&u[1],&u[2],&u[3]);
    a=u[0]+u[1]+u[2]+u[3]-5;
    b=u[0]*(u[1]-u[2]/u[3]+8);
    c=u[0]*u[1]/u[2]*u[3];
    x=(a+b+2)*3-u[(c+3)%4];
    y=(c*100-13)/a/(u[b%3]*5);
    if((x+y)%2==0)
        z=(a+b+c+x+y)/2;
    z=(a+b+c-x-y)*2;
    printf("%d\n",x+y-z);
}
//輸入:2 5 7 4

2.

//2004.4.2
#include <stdio.h>

int number,ndata,sum;
int data[100];//data[101] pascal 
void solve(int s,int sign,int n){
    int i;
    for(i=s;i<ndata;i++){//i<=ndata pascal
        sum+=sign*(number/n/data[i]);//number/(n*data[i]) pascal
        solve(i+1,-sign,n*data[i]);
    }
}

int main(){
    int i;
    
    scanf("%d %d",&number,&ndata);
    sum=0;
    for(i=0;i<ndata;i++)//for(i=1;i<=ndata;i++) pascal
        scanf("%d",&data[i]);
    solve(0,1,1);//solve(1,1,1); pascal
    printf("%d\n",sum);
    return 0;
}
//輸入:1000 3 5 13 11
 

3.

//2004.4.3
#include <stdio.h>

char c[3][200];
int s[10];
int m,n;

void numara(){
    int cod;
    int i,j,nr;
    for(j=0;j<n;j++){
        nr=0;
        cod=1;
        for(i=0;i<m;i++)
            if(c[i][j]=='1'){
                if(!cod){
                    cod=1;
                    s[nr]++;
                    nr=0;
                }
            }else
                if(cod){
                    nr=1;
                    cod=0;
                }else
                    nr++;
        if(!cod)
            s[nr]++;
    }
}

int main(){
    int i;
    scanf("%d %d\n",&m,&n);//scanf("%d%d",&m,&n);
    for(i=0;i<m;i++)
        gets(c[i]);//scanf("%s",c[i]);
    numara();
    for(i=0;i<n;i++)//原文for i := 1 to m do pascal有誤,應改成 for i := 1 to n do
        if(s[i]!=0)
            printf("%d %d ",i,s[i]);
    return 0;
}
//輸入:
//3 10
//1110000111 
//1100001111
//1000000011


4.

//2004.4.4 該題pascal轉C、C++要注意 
#include <stdio.h>

const int u[3]={1,-3,2};
const int v[2]={-2,3};
int n,sum;

int g(int n){
    int i,sum;
    sum=0;
    for(i=1;i<=n;i++)
        sum+=u[i%3]*i;
    return sum;
}
int main(){
    int i;
    sum=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        sum+=v[i%2]*g(i);
    printf("%d\n",sum);
    return 0;
}
//輸入:103
 


問題解答:

1.

該題比較簡單,順着程序執行就可以了,

答案:263

該題考點,數組,除,模運算。

1簡單

2.比較難得遞歸的題目一次性做對,很是高興,該題難度中等,是練遞歸的好題目。

思考過程如下:


答案:328

2中等

3.輸出怎麼跟想的不一樣,跟蹤了程序,才發現,敲代碼時,縮進格式影響了閱讀。

本題找不到s[i]初始化,雖然編譯器默認初始化爲0,出題者的疏忽吧。

思考過程如下:



寫到i=5,就可以大致猜出,在統計列上連續0的個數,s[2]表示連續2個0,s[3]表示連續3個0,s[1]表示單獨0。

答案:1 4 2 1 3 3

3中等

4.

本題是一個三岔路,找g(i)規律,找sum規律,還是找g(i)和sum的規律。

本題關鍵是找g(i)的規律。經驗告訴我們,大批量的數據是有規律的,等差,等比,或者能寫出遞推公式。

http://wenku.baidu.com/link?url=oTA4VH-47iUcjYM_BiQwVqp5-XqZ0ZbUfJmr_TL_F87-fvrHJwRNgK9V-uT5ISZiy3ubVtYzeQafrzz82qWTPc2kYPy-LTpvgC6nZ6x_oZC介紹得比較詳細。

算出g(1),g(2),g(3)......g(16)值

-3,1,4,-8,2,8,-13,3,12,-18,4,16,-23,5,20,-28

發現

-3,-8,-13,-18,-23,-28

1,2,3,4,5

4,8,12,16,20

三組等差數列

sum=3*(g(1)+g(3)+g(5)+......+g(103))-2*(g(2)+g(4)+g(6)+......+g(102))



這個題目能做出,數學水平很不一般啊,一般人沒有耐心分析到這個程度。

4難

2.第十一屆(NOIP2005)

問題

1.

//2005.4.1
#include <stdio.h>

int main(){
    int a,b,c,p,q;
    int r[3];
    scanf("%d%d%d",&a,&b,&c);
    p=a/b/c;
    q=b-c+a+p;
    r[0]=a*p/q*q;
    r[1]=r[0]*(r[0]-300);
    if(3*q-p%3<=r[0]&&r[2]==r[2])
        r[1]=r[r[0]/p%2];
    else
        r[1]=q%p;
    printf("%d\n",r[0]-r[1]);
    return 0;
}
//輸入:100 7 3

2.

//2005.4.2
#include <stdio.h>
#include <stdlib.h>

int a[50];
int n,sum;
void work(int p,int r){
    int i,j,temp;
    if(p<r){
        i=p-1;
        for(j=p;j<r;j++){
            if(a[j]>=a[r]){
                i++;
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
        }
        temp=a[i+1];
        a[i+1]=a[r];
        a[r]=temp;
        work(p,i);
        work(i+2,r);
    }
}

int main(){
    int i;
    sum=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    work(0,n-1);
    for(i=0;i<n-1;i++)
        sum+=abs(a[i+1]-a[i]);//abs stdlib.h
    printf("%d\n",sum);
    return 0;
}
//輸入:10 23 435 12 345 3123 43 456 12 32 -100 

3.

//2005.4.3
#include <stdio.h>
#include <string.h>


int main(){
    char str[60];
    int len,i,j;
    int nchr[26];
    char mmin;
    
    mmin='z';
    scanf("%s",str);
    len=strlen(str);
    for(i=len-1;i>=1;i--)
        if(str[i-1]<str[i])
            break;
    if(i==0){
        printf("No result!\n");
        return 0;
    }
    for(j=0;j<i-1;j++)
        putchar(str[j]);
    memset(nchr,0,sizeof(nchr));
    for(j=i;j<len;j++){
        if(str[j]>str[i-1]&&str[j]<mmin)
            mmin=str[j];
        nchr[str[j]-'a']++;
    }
    nchr[mmin-'a']--;
    nchr[str[i-1]-'a']++;
    putchar(mmin);
    for(i=0;i<26;i++)
        for(j=0;j<nchr[i];j++)
            putchar(i+'a');
    putchar('\n');
    return 0;
}
//輸入:zzyzcccbbbaaa

4.

//2005.4.4 
//該程序無法運行, 但可以根據程序來推測答案
#include <stdio.h>

long g(long k){
    if(k<=1)
        return k;
    return (2002*g(k-1)+2003*g(k-2))%2005;
}
int main(){
    long n;
    scanf("%ld",&n);
    printf("%ld\n",g(n));
    return 0;
}
//輸入:2005
 

問題解答:

1.

該題比較簡單,按順序執行即可。

p=100/7/3=4

q=7-3+100+4=108

r[0]=100*4/108*108=324

r[1]=324*(324-300)=7776

3*108-4%3<=324 r[2]==r[2]

r[1]=r[324/4%2]=r[1]=7776

r[0]-r[1]=324-7776=-7452

答案:-7453

2.

進行程序模擬:


答案:3223

2中等,遞歸。

3.思考過程如圖所示:


答案:zzzaaabbbcccy

3簡單

4.試了g(2005),g(2004),g(0),g(1),g(2),g(3),g(4)發現吃不消做。

搜索http://wenku.baidu.com/view/94eb85d076eeaeaad1f3301c.html摘抄如下:





答案:31

2016-12-18 22:30

提供http://tieba.baidu.com/p/1399841177做法


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章