NOIP(第02届)--1996--提高组--复赛--试题与答案(NA02)

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

中小学编程红宝书.zip

关键词:

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

 

 

 

第1题:比赛安排

1、        说明:

A、试题类型:

       逻辑应用。

 

B、算法模型:

       算法训练。

 

C、试题说明:

       题目有错误,输出格式应该为<i>A-B C-D

 

首先观察题目,任何两支队伍都只要比赛一场,所以选择一个map二维数组来记录是否队伍间的比赛情况,然后,观察每一行输出,1-n只出现过一次,所以此处定义一个一维数组来记录在这一次输出中,某一个队伍是否参加了比赛。

2、代码

#include<iostream>

#include<cstring>

#include<cmath>

using namespace std;

 

int n,m,book[100],map[100][100];

 

void dfs()

{

    int k=0;

    memset(book,0,sizeof(book));

    while (1)

    {

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

        {

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

            {

                if (map[i][j]==0&&book[i]==0&&book[j]==0)

                {

                    k++;

                    book[i]=1;

                    book[j]=1;

                    map[i][j]=1;

                    cout<<i<<"-"<<j<<" ";

                }

                if (k==n/2)

                                   return ;

            }

        }

    }

}

 

int main()

{

    cin>>n;

    n=pow(2,n);

    m=n-1;

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

    {

        cout<<"<"<<i<<">";

        dfs();

        if (i!=m)

                     cout<<endl;

    }

}

第2题:数制转换

1、说明

A、试题类型:

       数制问题。

 

B、算法模型:

       逻辑与数制的结合。

 

C、试题说明:

       无。

 

      

2、代码

#include<stdio.h>

#include<string.h>

 

int main()

{

    char c[25];

    int stl,i,j=0,a,b,d[25],k=0,sum,e[25];

    gets(c);

    stl=strlen(c);

    sum=a=b=0;

    for(i=0;i<stl;i++)

    {

        if(c[i]!='<')

        {

            d[k++]=c[i]-'0';

        }

        else

        {

                     break;

        }

    }

 

    i++;

 

    for(i;i<stl;i++)

    {

        if(c[i]!='>')

        {

                     a=a*10+c[i]-'0';

        }

        else

        {

                     break;

        }

    }

 

    i++;

 

    for(i;i<stl;i++)

    {

              b=b*10+c[i]-'0';

    }

 

    for(i=0;i<k;i++)

    {

              sum=sum*a+d[i];

    }

 

    while(sum>0)

    {

        e[j++]=sum%b;

        sum/=b;

    }

 

    for(i=0;i<k;i++)

    {

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

    }

 

    printf("<%d>=",a);

 

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

    {

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

    }

 

    printf("<%d>\n",b);

}

第3题:挖地雷

1、说明

A、试题类型:

       动态规划。

 

B、算法模型:

       图与倒推。

 

C、试题说明:

       从图的角度看,是一个有向图。

从动态规划角度来说,倒推的方式: 用f[i]记录从i出发能够挖到的最多的地雷数,b[i][j]表示从i到j是否连通,a[i]表示i处的地雷数。

 

状态转移方程:

 

if(b[i][j]){

   f[i]=max(f[i],f[j]+a[i])

}

 

有了状态转移方程,最值就能够得出来了,题目中还要求输出挖地雷最多时的顺序,也就是需要记录下每次的路径,用pre[i]来存储从i到达的下一点,和链表思路很像。

2、代码

#include<iostream>

#include <algorithm>

using namespace std;

 

int n;

int a[1000];

int f[1000],pre[1000];

bool b[1000][1000];

 

int main()

{

       cin>>n;

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

              cin>>a[i];

      

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

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

              {

                     cin>>b[i][j];

              }

             

              f[n]=a[n];

             

              for(int i=n-1;i>=1;i--)

              {

                     int fj=0,path=0;

                    

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

                     {

                            if(b[i][j]&& f[j]>fj){

                                   fj=f[j];

                                   path=j;

                            }     

                     }

                     f[i]=fj+a[i];

                     pre[i]=path;

              }

             

              int k=1;

             

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

                     if(f[i]>f[k]) k=i;

                    

                     cout<<k<<" ";

                     int m;

                     m=f[k];

                     k=pre[k];

                    

                     while(k)

                     {

                            cout<<k<<" ";

                            k=pre[k];

                     }

                    

                     cout<<endl;

                     cout<<m;

                     return 0;

}

 

第4题:砝码称重

1、说明

A、试题类型:

       STL应用。

 

B、算法模型:

       set。

 

C、试题说明:

       穷举:穷尽的方法将砝码所有的组成情况都计算出来,然后去掉非重复的即可,这种办法十分的笨拙,在组成可测量的重量重复次数比较多的时候,效果很差。

 

C++ set 关联容器。set关联容器可以自动的去重复和排序,效率好一些。

 

1g砝码,只能称出1g,如果有一个2g砝码能称出1g,2g,3g的重量。

 

3种情况由来,它有原先的1g,与新加入的2g砝码自己称出的重量2g和1g+2g,去掉重复后组成的。那么此时如果在给一个1g砝码,可以称出的重量是,1g,2g,3g,4g:它是由原先的1g,2g,3g,与新加入的1g砝码自己称出的重量1g和1g+1g,1g+2g,1g+3g,去掉重复后组成的。

 

规律:n个砝码可以看成是n-1个砝码后再重新给1个砝码的情况。因此利用set里面的自动去重复可以完成部分工作,只需要写出新给1个砝码后所增加的情况就可以了。

2、代码

#include <iostream>

#include <set>

#include <vector>

using namespace std;

 

class Solution

{

public:

       int sum;

       vector<int> everyweight;

       Solution();

       Solution(vector<int> &numweight, vector<int> &every) :everyweight(every), current({ 0 }), next({ 0 })

       {

              for (auto j = numweight.cbegin(),m=everyweight.cbegin(); j != numweight.cend(); j++,m++) //循环不同种类的砝码

              {

                     for (int k = 1; k <= *j; k++)   //对输入的砝码个数进行循环

                     {

                            for (auto i = current.cbegin(); i !=current.cend(); i++)

                            {

                                   next.insert(*i + (*m));    //向下一个set关联容器中存入能称出的重量

                            }

                            current = next;//更新关联容器

                     }

              }

              sum = current.size()-1;

       }

private:

       set<int> current;

       set<int> next;

};

 

int main()

{

       vector<int> numweight;

       vector<int> every = { 1, 2, 3, 5, 10, 20 };

       int n;

       while (cin>>n)

       {

              numweight.push_back(n);

       }

       Solution solution(numweight,every);

       cout << solution.sum << endl;

       return 0;

}


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