NOIP(第13届)--2007--提高组--复赛--试题与答案(NA13)

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

中小学编程红宝书.zip

 

第1题:统计数字

1、说明

A、试题类型:

       基本算法。

 

B、算法模型:

       排序。

 

C、试题说明:

复杂度最优的肯定是桶排序。

但是,值域是1500000000,桶肯定是开不下的。

所以考虑,桶有什么缺点呢,就是会出现很多空桶。这些空桶大大浪费了空间。

考虑直接排遍序,然后相同的数肯定就在一起了。然后统计每段连续的数的个数就好了。

2、代码

#include<bits/stdc++.h>

using namespace std;

 

#define re register

#define ll long long

#define get getchar()

#define in inline

 

in int read()

{

    int t=0; char ch=get;

    while(ch<'0' || ch>'9') ch=get;

    while(ch<='9' && ch>='0') t=t*10+ch-'0',ch=get;

    return t;

} //快读

 

struct num

{

    int id,sum;

}a[200010]; //每个数出现的次数及它的值

 

int tot,n,h[200010]; //tot表示有多少个不同的数, h为初始序列

 

int main()

{

    n=read(),a[0].id=-199; //初始化

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

        h[i]=read();  //输入

      

    sort( h+1,h+n+1); //按从小到大排序

      

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

    {

        if(a[tot].id==h[i])a[tot].sum++; //如果当前数与之前的数相同,则将之前数的个数+1

        else a[++tot].id=h[i],a[tot].sum=1; //如果不同,则将不同的数的总数+1,然后赋值

    }

    for(re int i=1;i<=tot;i++)

        cout<<a[i].id<<' '<<a[i].sum<<endl; //输出

      

    return 0;

}

第2题:字符串的展开

1、说明

A、试题类型:

       字符串问题。

 

B、算法模型:

       字符串逻辑推导。

 

C、试题说明:

1.      一个一个字符遍历,寻找。

 

2.      判断-前后两个字符,是否满足条件。

 

2.1 若满足, 则根据p3决定输出顺序,根据p2决定输出的字符个数和类型

for(p3==1?j=first+1:j=end-1; p3==1?j<end:j>first; p3==1?j++:j-- ) //p==1顺序。

 

2.2若不满足,直接输出。

2、代码

#include<bits/stdc++.h>

 

using namespace std;

 

int p1,p2,p3;

string s;

char first1,end1,f,p;

int i=0,j;

 

int main()

{

       cin>>p1>>p2>>p3; 

       cin>>s;

       while(s[i])

       {

              first1=s[i-1];

              end1=s[i+1];

              f=s[i];

             

              if(f=='-'&&end1>first1&&(first1>='0'&&end1<='9'||first1>='a'&&end1<='z'))

              {

                     for(p3==1?j=first1+1:j=end1-1; p3==1?j<end1:j>first1; p3==1?j++:j-- )

                     {

                            p=j;

                            if(p1==2)

                                   p=(p>='a')?p-32:p;

                            else if(p1==3)

                                   p='*';

                            for(int k=0;k<p2;k++)

                            {

                                   printf("%c",p);

                            }

                     }

              }

              else

                     printf("%c",f);

              i++;

       }

       return 0;

}

 

第3题:矩阵取数游戏

1、说明

A、试题类型:

       数学模型。

 

B、算法模型:

       矩阵。

 

C、试题说明:

       每一行是互不影响,然后分开处理。

反着来考虑,令                                               表示加到左端点为右端点为的最大得分就行了。

 

2、代码

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <iomanip>

using namespace std;

 

const int maxnum = 35;

const int M = 100000000;

typedef unsigned long long ll;

int n, m, map[81][81];

 

struct highNum

{

    ll num[maxnum];

      

    highNum(int length = 1)

    {

        memset(num, 0, sizeof(num));

        num[0] = length;

    }

      

    highNum operator = (highNum b)

    {

        memcpy(num, b.num, sizeof(b.num));

        return *this;

    }

      

    highNum operator = (int b)

    {

        *this = highNum();

        num[num[0]] = b;

        return *this;

    }

      

    bool operator < (const highNum& b) const

    {

        if(num[0] < b.num[0]) return true;

        if(num[0] == b.num[0])

        {

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

            {

                if(num[i] > b.num[i]) return false;

                if(num[i] < b.num[i]) return true;

            }

        }

        return false;

    }

      

    highNum operator + (const highNum& b) const

    {

        highNum c = highNum(max(num[0], b.num[0]));

        for(int i = 1; i <= c.num[0]; ++i)

        {

            c.num[i] += num[i] + b.num[i];

            c.num[i + 1] += c.num[i] / M;

            c.num[i] %= M;

        }

        while(c.num[c.num[0] + 1] > 0)

        {

            ++c.num[0];

            c.num[c.num[0] + 1] += c.num[c.num[0]] / M;

            c.num[c.num[0]] %= M;

        }

        return c;

    }

      

    highNum operator * (const int b) const

    {

        highNum c = highNum(num[0]);

        for(int i = 1; i <= c.num[0]; ++i)

        {

            c.num[i] += num[i] * b;

            c.num[i + 1] += c.num[i] / M;

            c.num[i] %= M;

        }

        while(c.num[c.num[0] + 1] > 0)

        {

            ++c.num[0];

            c.num[c.num[0] + 1] += c.num[c.num[0]] / M;

            c.num[c.num[0]] %= M;

        }

        while(c.num[c.num[0]] == 0 && c.num[0] > 1) --c.num[0];

        return c;

    }

      

    highNum operator * (const highNum& b) const

    {

        highNum c = highNum(num[0] + b.num[0]);

        for(int i = 1; i <= num[0]; ++i) for(int j = 1; j <= b.num[0]; ++j)

        {

            c.num[i + j - 1] += num[i] * b.num[j];

            c.num[i + j] += c.num[i + j - 1] / M;

            c.num[i + j - 1] %= M;

        }

        while(c.num[c.num[0] + 1] > 0)

        {

            ++c.num[0];

            c.num[c.num[0] + 1] += c.num[c.num[0]] / M;

            c.num[c.num[0]] %= M;

        }

        while(c.num[c.num[0]] == 0 && c.num[0] > 1) --c.num[0];

        return c;

    }

};

 

ostream& operator << (ostream& o, highNum& b)

{

    o << b.num[b.num[0]];

    o.setf(ios::fixed);

    o.width(8);

    o.fill('0');

    for(int i = b.num[0] - 1; i >= 1; --i) o << b.num[i];

    return o;

}

 

highNum ans, f[81][81], pw[81];

 

void init()

{

    cin >> n >> m;

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

        cin >> map[i][j];

    pw[1] = 2;

    for(int i = 2; i <= m; ++i) pw[i] = pw[i - 1] * 2;

}

 

void work(int row)

{

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

        f[i][j] = highNum();

    for(int i = 1; i <= m; ++i) f[i][i] = pw[m] * map[row][i];

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

    {

        int j = i + p;

        f[i][j] = max(f[i + 1][j] + pw[m - p] * map[row][i], f[i][j - 1] + pw[m - p] * map[row][j]);

    }

    ans = ans + f[1][m];

}

 

int main()

{

    init();

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

              work(i);

    cout << ans;

    return 0;

}

第4题:树网的核

1、说明

A、试题类型:

       基本数据结构。

 

B、算法模型:

       树、图、二分应用。

 

C、试题说明:

       基本逻辑处理。

 

 

2、代码

int n,f[666][666],s;

 

int main()

{

       ios::sync_with_stdio(false);

       cin>>n>>s;

 

       rep(i,1,n) rep(j,1,n) f[i][j] = 1e7;

       rep(i,1,n) f[i][i] =0;

 

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

       {

              int  u,v,w;

              cin>>u>>v>>w;

              f[u][v] = f[v][u] = w;

       }

 

       rep(k,1,n) rep(i,1,n) rep(j,1,n) f[i][j] = min(f[i][j],f[i][k]+f[k][j]);

       int pos1,pos2,maxlen = -1;

 

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

       {

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

              {

                     if(f[i][j]>maxlen)

                     {

                            pos1 = i,pos2 = j,maxlen  = f[i][j];

                     }

              }

       }

      

       int ans = 1e7;

 

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

       {

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

              {

                     if(f[i][j]+f[j][pos2]+f[i][pos1]!=maxlen)

                            continue;

                     if(f[i][j]>s)

                            continue;

                    

                     int temp  =-1;

 

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

                     {

                            temp = max(temp,(f[i][k]+f[j][k]-f[i][j])/2  );

                     }

                     ans = min(ans,temp);

              }

       }

       cout<<ans;

}



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