NOIP(第03届)--1997--提高组--复赛--试题与答案(NA03)

2022-07-04 已有0人阅读 作者: 美联航达

中小学编程红宝书.zip

关键词:

北京中关村;海淀黄庄;北京大学;清华大学。少儿编程;中小学编程;信息学竞赛;计算机竞赛;NOIP竞赛;CSP-J/S竞赛;NOI竞赛。1997年、提高组、复赛,第3届。

 


第1题:素数

1、说明

A、试题类型:

       送分题.

 

B、算法模型:

       素数与结构的结合.

 

C、试题说明:

       逻辑与数学的结合。

2、代码

#include <stdio.h>

#define N 10

 

int A[N+1][N+1];                /*格子*/

int B[N*N+1]={0,1,0};           /*为已经填入的数标记*/

int pos=1;                      /*指向当前格子*/

 

struct

{     

    int x;      

    int y;

    int num;

}D[N*N+1];

 

int isPrime(int m)       /*判断是否是素数*/

{

    int i;

      

    if(m==2)

        return 1;

      

    if(m==1 || m%2==0)    

        return 0;

      

    for(i=3;i*i<=m;)   

    {     

        if(m%i==0)    

            return 0;

        i+=2;

    }

      

    return 1;

}

 

int selectNum(int start,int n)       /*从start起选择一个可填入的最小整数*/

{     

    int j;

    for(j=start;j<=n*n;j++)

        if(!B[j])   

            return j;

             

              return 0;

}

 

 

int check(int x,int y)   /*检查A[x][y]填入的数是否合理*/

{     

    if(x>1 && !isPrime(A[x][y]+A[x-1][y]))      

        return 0;

      

    if(y>1 && !isPrime(A[x][y]+A[x][y-1]))

        return 0;

      

    return 1;

}

 

extend(int n)                     /*为下一个方格找一个尚未使用过的整数*/

{

    D[++pos].num=selectNum(2,n);

    A[D[pos].x][D[pos].y]=D[pos].num;

    B[D[pos].num]=1;

}

 

void change(int n)   /*为当前方格找下一个尚未使用过的整数(找不到回溯)*/

{     

    int j;

    while(pos>=1 && (j=selectNum(D[pos].num+1,n))==0)

        B[D[pos--].num]=0;

      

    if(pos<1)

    {     

        printf("NO"); 

        return;   

    }

      

    B[D[pos].num]=0;

    D[pos].num=j;

    A[D[pos].x][D[pos].y]=D[pos].num;

    B[j]=1;

}

 

 

 

void OutputResult(int n)       /*输出结果*/

{

    int i,j;

    for(i=1;i<=n;i++) 

    {     

        for(j=1;j<=n;j++) 

            printf("%4d",A[i][j]);

             

        printf("/n");   

    }

}

 

void find(int n)

{     

    int ok=1;

    do

    {     

        if(ok)     

            if(pos==n*n)                      

                     {     

                OutputResult(n);  

                return ;  

            }

            else 

                            extend(n);

                    

                     else 

                            change(n);

                    

                     ok=check(D[pos].x,D[pos].y);

    }while(pos>=1);

}

 

 

main()

{

    int i,j;

    int n;

      

    do  

    {

        printf("input the n:");

        scanf("%d",&n);

    }while(n<1||n>10);

      

    for(i=1;i<=n;i++)                     /*初始化数组A*/

        for(j=1;j<=n;j++)

            A[i][j]=0;

             

              A[1][1]=1;

             

              for(i=1;i<=n;i++)                   /*初始化数组D*/    

              {

                     D[i].x=1;

                     D[i].y=i;

                     D[i].num=0;  

              }

             

              D[1].num=1;

             

              for(;i<2*n;i++)     

              {     

                     D[i].x=i-n+1;

                     D[i].y=1;

                     D[i].num=0;

              }

             

              if(n>1)

                     for(;i<=n*n;i++)   

                     {

                            D[i].x=2+(i-2*n)/(n-1);

                            D[i].y=i-2*n+1-(D[i].x-2)*(n-1)+1;

                            D[i].num=0;

                     }

                    

                     find(n);

                     getch();

}

第2题:代数表达式

1、说明

A、试题类型:

       经典表达式问题.

 

B、算法模型:

模拟问题.

 

C、试题说明:

       无。

2、代码

#include<cstdio>

#include<cstdlib>

#include<cstring>

#define maxn 1000000

using namespace std;

 

char s[maxn];

 

void error_1()

{

       int i,j,k=strlen(s);

 

       for(i=0;s[i]!=';' && i<k;i++)

              if(!(s[i]=='a' || s[i]=='b' || s[i]=='c' ||

                     s[i]=='+' || s[i]=='-' || s[i]=='*' ||

                     s[i]=='/' || s[i]=='(' || s[i]==')')

                     )

              {

                     printf("ERROR 1\n");

                     exit(0);

              } 

}

 

void error_2()

{

       int i,j,k=strlen(s);

 

       for(i=j=0;s[i]!=';' && i<k;i++)

    {

              if(s[i]=='(')

                     j++;

 

              if(s[i]==')')

                     j--;

 

              if(j<0)

              {

                     printf("ERROR 2\n");

                     exit(0);

              }

    }

 

       if(j!=0)

       {

              printf("ERROR 2\n");

              exit(0);

       } 

}

 

int main()

{

       //freopen("1.in","r",stdin);

       gets(s),error_1(),error_2();

      

       int p=0,i,j,k=strlen(s);

 

       for(i=0;s[i]!=';' && i<k;i++)

    {

              if(s[i]=='a' || s[i]=='b' || s[i]=='c')

        {

                     p++;

                     if(p!=1)break;

        }

              if(s[i]=='+' || s[i]=='-' || s[i]=='*' || s[i]=='/')

                     p--;

    }

       if(p!=1)

              printf("ERROR 3\n");

 

       else

              printf("OK\n"); 

 

       return 0;

}

 

第3题:骑士游历

1、说明

A、试题类型:

       算法问题。

 

B、算法模型:

       DP。

 

C、试题说明:

       dp思想单一,通过相邻元素的状态推出当前元素的状态,不同的题就是各元素的关系不同;

 

棋盘的每一个点当做一个终点,f[i][j]表示起点到ij列的点的路径总条数。显然起点的值是1;之后每个点的路径条数就等于到这个点的前一个点的所有可能点的路径数之和。

2、代码

#include<iostream>

#include<cstdio>

using namespace std;

 

int n,m,a,b,c,d;

long long f[51][51];

 

int main()

{

       scanf("%d%d%d%d%d%d",&n,&m,&b,&a,&d,&c);

      

       f[a][b]=1;

       for(int j=b+1;j<=m;j++)

       {

              for(int i=1;i<=n;i++)

              {

                     if(j>1)

                     {

                            if(i>=3) f[i][j]+=f[i-2][j-1];

                            if(i<=n-2) f[i][j]+=f[i+2][j-1];

                     }

                     if(j>2)

                     {

                            if(i>=2) f[i][j]+=f[i-1][j-2];

                            if(i<=n-1) f[i][j]+=f[i+1][j-2];

                     }

              }

       }

       cout<<f[c][d];

}

 

IT航班支持----中小学编程比赛汇总:

 

第一部分:国内比赛(IT航班支持)   

1、软件能力认证(CSP-JS) 

2、全国青少年信息学奥林匹克联赛(NOIP)    

3、全国青少年信息学奥林匹克竞赛(NOI)

4、中国青少年………………………  

5、………………………创新挑战赛  

6、全国青少年………………………  

7、………………………

8、 恩欧希教育信息化发明创新奖  

9、世界机器人大赛(WRC) 

10、………………………大赛    

11、少………………………智能教育成果展示大赛 

12、“明天小小科学家”奖励活动

13、………………………    

14、………………………    

15、国际信息学……………………… 

16、………………………    

 

第二部分:国际比赛(IT航班支持)   

17、………………………    

18、国际………………………    

19、………………………

20、美国信息学……………………… 

21、加拿大……………………… 

22、官方邀请赛 (CCO)     

23、国际计算思维………………………    

24、美国计算机……………………… 

25、澳大利亚………………………    

 

第三部分:企业比赛(IT航班支持)   

26、微软MTA    

27、………………………挑战赛 

28、………………………科学奖 

29、………………………学奖    

30、………………………创新挑战赛 

31、………………………挑战赛 

32、………………………芯计算机表演赛 

33、………………………大赛    

 

第四部分:Scratch相关竞赛(IT航班支持)    

34、全国中小学生电脑制作大赛     

35、………………………    

36、………………………    

37、………………………    

 

第五部分:其它(IT航班支持)   

38、NOI夏令营  

39、NOI冬令营(NOIWC)  

40、全国青少年……………………… 

41、国际青少年………………………

 

 

联系方式:

A、官方网址:

http://www.itflight.net


B、微信公众号:

添加微信,获取资料。

image.png

 



关注公众号,获取动态。

image.png