NOIP 提高组 初赛 四、阅读程序写结果 习题集(二)NOIP2000-NOIP2001

来源:互联网 发布:sleep函数c语言实现 编辑:程序博客网 时间:2024/05/17 04:53

NOIP 提高组 初赛 四、阅读程序写结果 习题集(二)NOIP2000-NOIP2001

1.第六届(NOIP2000)

问题(原文是pascal,按题意,本人改写成C,C++版本):

1.

//NOIP2000 3.1
#include <stdio.h>
#include <math.h>

const int n=7,m=6;

float disp(int x1,int y1,int x2,int y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main(){
    int i,j,x0,y0,x1,y1,x2,y2;
    float d;
    int p;
    int g[n+1][m+1];
    for(i=0;i<=n;i++)
        for(j=0;j<=m;j++)
            g[i][j]=0;
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    g[x1][y1]=1;
    g[x2][y2]=1;
    p=1;
    while(p){
        p=0;
        d=disp(x1,y1,x2,y2);
        x0=x1;
        y0=y1;
        for(i=4;i<=n;i++)
            for(j=0;j<=m;j++)
                if(d>disp(i,j,x2,y2)&&g[i][j]==0){
                    d=disp(i,j,x2,y2);
                    x0=i;
                    y0=j;
                }
        if(x0!=x1||y0!=y1){
            x1=x0;
            y1=y0;
            p=1;
            g[x1][y1]=1;
        }
        d=disp(x1,y1,x2,y2);
        x0=x2;
        y0=y2;
        
        for(i=0;i<=3;i++)
            for(j=0;j<=m;j++)
                if(d<disp(x1,y1,i,j)&&g[i][j]==0){
                    d=disp(x1,y1,i,j);
                    x0=i;
                    y0=j;
                }
        if(x0!=x2||y0!=y2){
            x2=x0;
            y2=y0;
            p=1;
            g[x2][y2]=1;
        }
    }
    printf("%d %d %d %d\n",x1,y1,x2,y2);
    return 0;
}
//输入7 6 0 0
 

2.

//NOIP2000 3.2
#include <stdio.h>

int main(){
    int i,j,L,n,k,s,t;
    int b[11];
    scanf("%d%d",&L,&n);
    s=L;
    k=1;
    t=L;
    if(n>L){
        while(s<n){
            k++;
            t*=L;
            s+=t;
        }
        s-=t;
        n=n-s-1;
        for(i=1;i<=10;i++)
            b[i]=0;
        j=11;
        while(n>0){
            j--;
            b[j]=n%L;
            n/=L;  
        }
        for(i=10-k+1;i<=10;i++)
            printf("%c",'A'+b[i]);
    }else
        printf("%c\n",'A'+n-1);
    return 0;
}
//输入:4 167

问题解答:

1.

阅读跟踪程序,可以发现:

for(i=4;i<=n;i++)
            for(j=0;j<=m;j++)
                if(d>disp(i,j,x2,y2)&&g[i][j]==0){
                    d=disp(i,j,x2,y2);
                    x0=i;
                    y0=j;
                }

是找最小的长度。

for(i=0;i<=3;i++)
            for(j=0;j<=m;j++)
                if(d<disp(x1,y1,i,j)&&g[i][j]==0){
                    d=disp(x1,y1,i,j);
                    x0=i;
                    y0=j;
                }

是找最大的长度。

思考过程如图所示:


(x1,y1)0,(x2,y2)0表示初始值。

(x1,y1)1,(x2,y2)1表示第一次循环后的值。

(x1,y1)2,(x2,y2)2表示第二次循环后的值。

依次类推,一共会进行8次循环,第6次找到(x2,y2)6值,第7次找到(x1,y1)7值。第8次p=0。

答案:4 3 0 2

1难,涉及矩阵,空间的变换,开始需要顺着程序跟踪,弄明白意思后,可以画二维图进行思考。

2016-12-13

2.执行过程如下:


答案:BBAC

1难2简单

2.第七届(NOIP2001)

问题(原文是pascal,按题意,本人改写成C,C++版本):

1.

//NOIP2001 3.1
#include <stdio.h>

int ack(int m,int n){
    if(m==0)
        return n+1;
    else if(n==0)
        return ack(m-1,1);
    else
        return ack(m-1,ack(m,n-1));
}

int main(){
    printf("%d\n",ack(3,4));
}

2.

//2001.3.2
#include <stdio.h>

int main(){
    int p,q,s,t;
    scanf("%d",&p);
    for(q=p+1;q<=2*p;q++){
        t=0;
        s=(p*q)%(q-p);
        if(s==0){
            t=p+q+(p*q)/(q-p);
            printf("%4d",t);
        }
    }
}
//输入:12
//输出:

3.

//2001.3.3
#include <stdio.h>

int main(){
    int i,j,h,m,n,k;
    int b[11];
    scanf("%d",&n);
    for(i=1;i<=10;i++){
        m=n;
        j=11;
        while(m>0){
            j--;
            b[j]=m%10;
            m/=10;
        }
        for(h=j;h<=10;h++)
            n+=b[h];
    }
    printf("%d\n",n);
    return 0;
}
//输入:1234
//输出:
 

4.

//2001.3.4
#include <stdio.h>

int main(){
    int x,y1,y2,y3;
    scanf("%d",&x);
    y1=0;
    y2=1;
    y3=1;
    while(y2<=x){
        y1++;
        y3+=2;
        y2+=y3;
    }
    printf("%d\n",y1);
    return 0;
}
//输入:23420
//输出:
 

问题解答:

1.

思考过程如下:

ack(0,0)=1

ack(0,1)=2

ack(0,2)=4

ack(0,3)=4

ack(0,4)=5

ack(1,0)=ack(0,1)=2

ack(1,1)=ack(0,ack(1,0))=ack(0,2)=3

ack(1,2)=ack(0,ack(1,1))=ack(0,3)=4

ack(1,3)=ack(0,ack(1,2))=ack(0,4)=5

ack(1,4)=ack(0,ack(1,3))=ack(0,5)=6

ack(2,0)=ack(1,1)=3

ack(2,1)=ack(1,ack(2,0))=ack(1,3)=5

ack(2,2)=ack(1,ack(2,1))=ack(1,5)=7

ack(2,3)=ack(1,ack(2,2))=ack(1,7)=9

ack(2,4)=ack(1,ack(2,3))=ack(1,9)=11

ack(3,0)=ack(2,1)=5

ack(3,1)=ack(2,ack(3,0))=ack(2,5)=13

ack(3,2)=ack(2,ack(3,1))=ack(2,13)=29

ack(3,3)=ack(2,ack(3,2))=ack(2,29)=61

ack(3,4)=ack(2,ack(3,3))=ack(2,61)=125

上述过程,略去一些小细节,但读者可以依照上述推导将该问题解决。

自下而上,对付递归的好办法。

2.思考过程如图所示:


答案:181 110 87 76 66 62 61 60

3.

根据该图找规律:


根据该图做计算:


答案:1348


4.

y1=1

y3=3

y2=4

 

y1=2

y3=5

y2=9

 

y1=3

y3=7

y2=16

 

y1=4

y3=9

y2=25

 

发现y2变化规律与第五届(NOIP1999)第二大题很象。

为了照顾之前学习的数学体系,令y1=n,y2=y(n)

y(1)=4

y(2)=y(1)+5=y(1)+2*2+1

y(3)=y(2)+7=y(2)+2*3+1

y(4)=y(3)+9=y(2)+2*4+1

……

y(n)=y(n-1)+2*n+1                               :1

有了通式后,开始推导y(n):

y(n)=y(n-2)+2*(n-1)+1+2*n+1              :2

y(n)=y(n-3)+2*(n-2)+1+2*n+1              :3

y(n)=y(n-4)+2*(n-3)+1+2*n+1              :4

……

y(n)=y(1)+2*(1+1)+1+……+2*n+1  :

2*(1+1)+1+……+2*n+1个数为x

n-x=1

x=n-1

等差数列

2*(1+1)+1+……+2*n+1=(2*(1+1)+1+2*n+1)*(n-1)/2

2*(1+1)+1+……+2*n+1=(n+3)(n-1)

 

y(n)=4+(n+3)(n-1)

输入数据:

y(n)=23420

n^2+2*n-23419=0

n=(-2+sqrt(4+4*23419))/2;(负值已被舍去)

n=-1+2*sqrt(5855);

手工计算:

75^2=5625

76^2=5776

77^2=5929

76.5^2=5852.25

假定:

sqrt(5855)=76.55

n=76.55*2-1

n=152.1

取大于152.1的整数

n=153

即y1=153

答案:153

 

1难2中等3中等4难

2016-12-9 20:55

0 0
原创粉丝点击