NOIP(第18届)--2012--普及组--复赛--试题与答案(NA18)

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

中小学编程红宝书.zip

关键词:

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

      2012年、普及组、复赛,第18届。

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



解析与答案:

 

1题:质因数分解

1、说明

A、试题类型:

       数字问题。

 

B、算法模型:

       质因数模型。

 

C、试题说明:

       n为两个质数之积,也就是说只要找到一个数能够被n整除,这个数一定是质数。

 

2为最小的质数,直接从2开始找,这里通过平方sqrt减小运算次数,找到质数,然后与n相除,找到另一个质数,比大小即可,选出最大那个即可。

2、代码

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

 

int main()

{

    int a,i,j,max;

    scanf("%d",&a);

    for(i=2;i<sqrt(a);i++){

        if(a%i==0){

            j=a/i;

            break;

        }

    }

    if(i>j){

        max=i;

    }

    else{

        max=j;

    }

    printf("%d",max);

    return 0;

}

2题:寻宝

1、说明

A、试题类型:

       基本推理。

 

B、算法模型:

       二维数组。

 

C、试题说明:

数学模型,这一题选用二维数组无疑是最好的选择。

 

要注意过滤掉多余的循环次数,x过大的时候,取模这一层的有楼梯总数count。但是取模=0的特殊情况。所以注意%count==0,num直接等于count就可以了。

 

查看房间的时候,房间编号l,在达到num就立即停止,以免出现后序继续遍历,直到大于num,这时房间号就改变了。

2、代码

#include<iostream>

#include<cstdio>

using namespace std;

 

int n,m,j,sum=0,i,num,l,k=0,count=0,t[10001][101]={0},x[10001][101]={0},c[10001]={0};

 

int main(void)

{

       freopen("treasure.in","r",stdin);

       freopen("treasure.out","w",stdout);

 

       cin>>n>>m;

 

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

              for(j=0;j<m;j++)cin>>t[i][j]>>x[i][j];

 

       cin>>k;

 

       l=k;

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

       {

              count=0;

              for(j=0;j<m;j++)

                     if(t[i][j]==1)count++;//统计这一层有多少个有楼梯的房间

              sum+=x[i][l];

              num=x[i][l]%count;//过滤多余的无效遍历

              if(num==0)//避免0出现的错误

              {

                     num=count;

              }

 

              j=0;

 

              while(j<=num)

              {

                     if(j==num)

                     {

                            l--;

                            if(l==-1)l=m-1;

                            break;//退出前,回滚一次房间号。

                     }

                     if(t[i][l]!=0)j++;//有楼梯的房间号累计

                     l++;

                     if(l==m)l=0;

              }

       }

 

       cout<<sum%20123<<endl;

 

       fclose(stdin);

       fclose(stdout);

 

       return 0;

}

3题:摆花

1、说明

 

A、试题类型:

       逻辑推理问题。

 

B、算法模型:

       方程与范围。

 

C、试题说明:

       上i盆花时的方案数,假设当前位置为i,如果要摆上j盆第k 种花。有如下方程:

 

dp[i]+=dp[ij]。其中1 < = i < = m , 1 < = j < = a

2、代码

#include<bits/stdc++.h>

#define INF 0x3f3f3f3f

#define eps 1e-8

#define pr pair<int,int>

using namespace std;

 

typedef long long ll;

 

const int mod=1000007;

 

int n,m;

int dp[105];

 

int main()

{

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

    int v;

    dp[0]=1;

 

    while(n--)

    {

        scanf("%d",&v);

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

            for(int j=min(i,v);j>=1;j--)

                dp[i]=(dp[i]+dp[i-j])%mod;

    }

    printf("%d\n",dp[m]);

    return 0;

}

 

4题:文化之旅

1、说明

A、试题类型:

       数据结构。

 

B、算法模型:

       队列深度优先搜索。

 

C、试题说明:

       不适宜使用Floyd,可以构造出数据,使用WA,深搜保险。

2、代码

#include <stdio.h>

#include <stdlib.h>

 

int n, k, m, s, t, distance[101][101], culture[101], fight[101][101], search[101], p = 0;

bool found = false;

 

int min(int a, int b)

{

    return (a > b ? b : a);

}

 

void DFS(int target)

{

    bool CanInqueue = true;

    int queue[101] = {0}, tail = 0;

    search[++p] = target;

    if (target == t)

    {

        found = true;

        return;

    }

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

    {

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

        {

            if (search[j] == i || culture[search[j]] == culture[i] || fight[culture[i]][culture[search[j]]] == 1)

            {

                CanInqueue = false;

                break;

            }

        }

        if (distance[target][i] == 1001)

            CanInqueue = false;

        if (CanInqueue)

            queue[++tail] = i;

        else

            CanInqueue = true;

    }

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

        distance[s][queue[i]] = min(distance[s][queue[i]], distance[s][target] + distance[target][queue[i]]);

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

        DFS(queue[i]);

    return;

}

 

int main()

{

    for (int i = 1, j; i < 101; ++i)

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

                     distance[i][j] = 1001;

              scanf("%d %d %d %d %d", &n, &k, &m, &s, &t);

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

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

              for (int i = 1, j; i <= k; ++i)

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

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

                     for (int i = 0, y, z, c; i < m; ++i, distance[z][y] > c ? distance[y][z] = distance[z][y] = c : c = 2147483646)

                            scanf("%d %d %d", &y, &z, &c);

                     DFS(s);

                     if (found)

                            printf("%d\n", distance[s][t]);

                     else

                            printf("-1\n");

                     return 0;

}



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

      

联系方式:

A、官方网址:

http://www.itflight.net


B、微信公众号:

添加微信,获取资料。

image.png

 



关注公众号,获取动态。

image.png