NOIP(第09届)--2003--普及组--复赛--试题与答案(NA09)

2022-07-07 已有0人阅读 作者: IT航班

中小学编程红宝书.zip


关键词:

北京中关村;海淀黄庄;北京大学;清华大学。少儿编程;中小学编程;信息学竞赛;计算机竞赛;NOIP;NOIP竞赛;CSP-J/S竞赛;NOI竞赛。北京中学;东坝。

      2003年、普及组、复赛,第9届。

面向6-18岁中小学生,做最专业的中小学编程教育。


解析与答案:

1题:乒乓球

1、说明

A、试题类型:

       基本推理。

 

B、算法模型:

       无。

 

C、试题说明:

       简单思维就是将11分制的结果与21分制的结果分而治之,而两者之间就仅仅是“11”与“21”的关系,没必要为了展示将两个合在一起。

 

分而治之的前提将输入条件用字符二维数组存下来。

 

 

2、代码

#include<bits/stdc++.h>

using namespace std;

 

char ch[2501][30];

bool pd = true;

//用于判断是否已经读到"E"了

 

int main()

{

       int tot = 0; // 用来记下题设所给字符串中有效字符串的个数,即在"E"之前的字符串。

       cin>>ch[0];

       int left = 0, right = 0;  //左比分,右比分

       while(pd)

       {

              int len = strlen(ch[tot]);

              for(int i = 0; i < len; i++)

              {

                     if(ch[tot][i]=='W') left++;

                     if(ch[tot][i]=='L') right++;

                     if(ch[tot][i]=='E')

                     {

                            cout<<left<<':'<<right<<endl;

                            pd = false;

                            i = len;

                            // 出现"E"即可结束for循环,不能再遍历下去了

                     }

                     if((left >= 11||right >= 11)&&(abs(left-right))>=2)

                     {

                            cout<<left<<':'<<right<<endl;

                            left = 0;

                            right = 0;

                            //出现一次符合条件的时刻,即将结果输出,并将比分清0;

                     }

              }

              if(pd)

              {

                     tot++;

                     cin>>ch[tot];//存储比赛信息,留21分制使用

                     //必须在合法的前提下,即还没有出现"E",才可以继续读取下一行字符串。

              }

       }

      

       cout<<endl;

      

       left = 0;

       right = 0;          //21分制的初始化

       for(int j = 0; j <= tot; j++)

       {

              int len = strlen(ch[j]);

              for(int i = 0; i < len; i++)

              {

                     if(ch[j][i]=='W') left++;

                     if(ch[j][i]=='L') right++;

                     if(ch[j][i]=='E')

                     {

                            cout<<left<<':'<<right<<endl;

                            return 0;//直接结束程序

                     }

                     if((left >= 21||right >= 21)&&(abs(left-right))>=2)

                     {

                            cout<<left<<':'<<right<<endl;

                            left = 0;

                            right = 0;

                     }

              }

       }   

}

 

    

 

 

2题:数字游戏

1、说明

A、试题类型:

       基本算法。

 

B、算法模型:

       DP。

 

C、试题说明:   

三维数组。

每一段都可以选择,所以要枚举m段;

每一个左边界都可以选择,所以要枚举n个左边界;

每一个右边界都可以选择,所以要枚举n个右边界;

还要破环成链。

2、代码

#include<bits/stdc++.h>

using namespace std;

 

struct dp

{

       int maxn;

       int minn;

}f[100][100][10];

 

int n,m,a[202],x,maxans = 0,minans = 0x3f3f3f3f;

 

int main()

{

       scanf("%d%d",&n,&m);

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

       {

              scanf("%d",&a[i]);

              a[i + n] = a[i];

       }

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

              a[i] += a[i - 1];

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

              for (int j = i;j <= 2 * n;j++)

                     f[i][j][1].maxn = ((a[j] - a[i - 1]) % 10 + 10) % 10;

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

            for (int j = i;j <= 2 * n;j++)

                f[i][j][1].minn = ((a[j] - a[i - 1]) % 10 + 10) % 10;

                     for (int i = 2;i <= m;i++)

                            for (int l = 1;l <= 2 * n;l++)

                                   for (int r = l + i - 1;r <= 2 * n;r++)

                                          f[l][r][i].maxn = 0x3f3f3f3f;

                                   for (int i = 2;i <= m;i++)

                                          for (int l = 1;l <= 2 * n;l++)

                                                 for (int r = l + i - 1;r <= 2 * n;r++)

                                                        f[l][r][i].minn = 0x3f3f3f3f;

                                                 for (int i = 2;i <= m;i++)

                                                        for (int l = 1;l <= 2 * n;l++)

                                                               for (int r = l + i - 1;r <= 2 * n;r++)

                                                                      for (int k = l + i - 2;k < r;k++)

                                                                             f[l][r][i].maxn = max(f[l][r][i].maxn,(f[l][k][i - 1].maxn * (a[r] - a[k]) % 10 + 10) % 10);

                                                                      for (int i = 2;i <= m;i++)

                                                                             for (int l = 1;l <= 2 * n;l++)

                                                                                    for (int r = l + i - 1;r <= 2 * n;r++)

                                                                                           for (int k = l + i - 2;k < r;k++)

                                                                                                  f[l][r][i].minn = min(f[l][r][i].minn,(f[l][k][i - 1].minn * (a[r] - a[k]) % 10 + 10) % 10);

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

                                                                                           {

                                                                                                  maxans = max(maxans,f[i][i + n - 1][m].maxn);

                                                                                                  minans = min(minans,f[i][i + n - 1][m].minn);

                                                                                           }

                                                                                          printf("%d\n%d",minans,maxans);

                                                                                           return 0;

}

    

 

 

 

3题:栈

1、说明

A、试题类型:

       基本数据结构。

 

B、算法模型:

       结构分析。

 

C、试题说明:

       特殊数学问题:

 

1.      可将进栈记为0,出栈记为1,那么问题即为求由n个0和n个1组成的字符串数,条件是每个1出现前必须有一个对应的0出现;

 

2.      可以推得方案数为总方案数减半,解与求01串的个数相同:n个0与n个1构成的序列方案数,使得任何一个前缀0的个数不少于1的个数;

 

3.      做法是将0看做在坐标系中向右走一步,1看做向上走一步,则问题可化简为从原点到(n,n)所有路线中一直处于y=x之下(不越过直线y=x)的不同路径方案数,方案数即为对应n的卡特兰数;

 

4.      没有要求取模,可以考虑使用高精度运算,输出n对应的卡特兰数即可;

2、代码

#include<iostream>

#include<cstdio>

#include<cmath>

#include<algorithm>

#include<cstring>

using namespace std;

 

int ans[100001]={},x=0;

 

void mul(int n)

{

       for(int i=1;i<=ans[0];++i)

       {

              ans[i]=ans[i]*n+x;

              x=ans[i]/10;

              ans[i]%=10;

       }

 

       while(x>0)

       {

              ans[0]++;

              ans[ans[0]]=x%10;

              x/=10;

       }

}

 

void div(int n)

{

       int q=0;

       for(int i=ans[0];i>=1;--i)

       {

              x=(ans[i]+q*10)%n;

              ans[i]=(ans[i]+q*10)/n;

              q=x;

       }

       while(ans[ans[0]]==0)

              ans[0]--;

}

 

int main()

{

       ans[0]=ans[1]=1;

       int n;

       scanf("%d",&n);

 

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

              mul(i);

 

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

              div(i);

 

       for(int i=ans[0];i>0;--i)

              printf("%d",ans[i]);

 

       printf("\n");

 

       return 0;

}

 

 

 第四题:麦森数

1、说明

A、试题类型:

       数字问题。

 

B、算法模型:

       万进制、大整数。

 

C、试题说明:   

求指数模板问题:

 

可参考大整数类模板:

 

1、万进制数,缩减时间;

2、位运算缩减时间。

 2、代码

#include<iostream>

#include<cstring>

#include<cmath>

using namespace std;

 

#define LEN 125

 

int result[LEN];

int tpow[LEN];

 

void mul(int *a,int *b)

{

    int temp[LEN];

    int jin,t;

 

    memset(temp,0,sizeof(int) * LEN);

 

    for(int i = 0;i < LEN; ++i)

       {

        jin = 0;

        for(int j = 0;j < LEN - i; ++j)

              {

            t = temp[i + j] + a[i] * b[j] + jin;

            temp[i + j] = t % 10000;

            jin = t / 10000;

        }

    }

    memcpy(a,temp,sizeof(int) * LEN);

}

 

int main()

{

    int p;

    int i,j;

 

    scanf("%d",&p);

    printf("%d\n",(int)(p * log10(2)) + 1);

    memset(result,0,sizeof(int) * LEN);

    result[0] = 1;

    memset(tpow,0,sizeof(int) * LEN);

    tpow[0] = 2;

 

    while(p > 0)

       {

        if(p & 1)

              {

            mul(result,tpow);

        }

        mul(tpow,tpow);

        p >>= 1;

    }

 

    result[0]--;

    j = 0;

 

    for(i = LEN - 1;i >= 0; --i)

       {

        if((j + 2) % 50 == 0)

            printf("%02d\n%02d",result[i] / 100,result[i] % 100);

        else if((j + 4) % 50 == 0)

            printf("%04d\n",result[i]);

        else

            printf("%04d",result[i]);

        j += 4;

    }

 

    printf("\n");

    return 0;

}

 

 






IT航班提供:课程视频、、课程书籍、竞赛辅导、少儿编程指导、课程采购、加盟、少儿编程资料、少儿编程课程、保送生、特长生、加分、中小学计算机教育、中小学信息学、竞赛、中小学信息学课程、人工智能、中小学编程加盟、少儿编程加盟、品牌加盟、技术加盟、技术指导、课程加盟、师资培训、中小学编程教辅资料、中小学编程教师培训、少儿编程教学书籍、少儿编程视频、教学书籍、教师培训、教学视频、CSP-J/S、中小学信息学课程服务、竞赛指导、课程提供、国内外计算机中小学计算机竞赛、信息学竞赛、信息学课程提供商、信息学奥林匹克。

      

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