2018CCCC天梯赛整理

L1-049. 天梯赛座位分配

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位参赛选手。令每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后。从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员…… 以此类推。如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。本题就要求你编写程序,自动为各校生成队员的座位号,从 1 开始编号。

输入格式:
输入在一行中给出参赛的高校数 N (不超过100的正整数);第二行给出 N 个不超过10的正整数,其中第 i 个数对应第 i 所高校的参赛队伍数,数字间以空格分隔。

输出格式:
从第 1 所高校的第 1 支队伍开始,顺次输出队员的座位号。每队占一行,座位号间以 1 个空格分隔,行首尾不得有多余空格。另外,每所高校的第一行按“#X”输出该校的编号X,从 1 开始。

输入样例:
3
3 4 2

输出样例:

#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

 解析:
 暴力思想,直接开出二维动态数组存数,当有一个排满的时候就要每次+2.直接模拟
 代码如下:
#include<bits/stdc++.h>
using namespace std;
int n;
int sum = 0;
int b[1000];
bool vis[1000];
vector<int> a[10000];
int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> b[i];
        sum += b[i]*10;
    }
    memset(vis,0,sizeof(vis));
    int ans = 1;
    int roww = 0;
    while(sum --)
    {
        for(int i = 0; i < n; i ++)
        {
            if(a[i].size() < b[i]*10)
            {
                a[i].push_back(ans);
                if(roww + 1 == n)
                {
                    ans += 2;
                }
                else
                {
                    ans += 1;
                }
            }

            if ( vis[i]==false && a[i].size() >= b[i]*10 )
            {
                roww ++;
                vis[i] = true;
            }

        }

    }

    for(int i = 0; i < n; i ++)
    {
        cout << "#" << i + 1 << endl;
        for(int j = 0; j < a[i].size(); j ++)
        {
            cout << a[i][j];
            if( j%10 == 9 ) cout << "\n";
            else cout << " ";
        }
    }


    return 0;
}

L1-050. 倒数第N个字符串

给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz }。这个序列的倒数第27个字符串就是 zyz。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。 
输入格式:

输入在一行中给出两个正整数 L(2 <= L <= 6)和 N(<= 105)。

输出格式:

在一行中输出对应序列倒数第 N 个字符串。题目保证这个字符串是存在的。
输入样例:

3 7417

输出样例:

pat

解析:
26进制思想,他让倒着输出那个字符串,那么我们找到最大值然后减去N(题目让输出的那个数)这样不就找到他正着对应的数字了嘛。然后每次除以基数。求求出相应结果啦
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[8];
/*
求出每一位的基数
*/
ll change(int l)
{
    ll sum = 1;
    for(int i = 0;i < l;i ++)
    {
        sum *= 26;
    }
    return sum;
}
/*
求出每一位对应的字母
*/
ll chage_a(ll x,int l)
{
    int cnt = 0;
    for(int i = l - 1;i >=0;i -- )
    {
        a[cnt ++] = x / change(i) + 'a';
        x %= change(i);
    }
    a[l] = '\0';
    return 0;

}
int main()
{
    int L,N;
    cin >> L >> N;
    ll x = change(L) - N;///将倒置的位数正着求。
    chage_a(x,L);
    puts(a);
    return 0;
}

L1-051. 打折

去商场淘打折商品时,计算打折以后的价钱是件颇费脑子的事情。例如原价 ¥988,标明打 7 折,则折扣价应该是 ¥988 x 70% = ¥691.60。本题就请你写个程序替客户计算折扣价。  
输入格式:
输入在一行中给出商品的原价(不超过1万元的正整数)和折扣(为[1, 9]区间内的整数),其间以空格分隔。

输出格式:
在一行中输出商品的折扣价,保留小数点后 2 位。
输入样例:

988 7

输出样例:

691.60
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int money, d;
    cin >> money >> d;
    printf("%.2f\n", (double)money*d/10);
    return 0;
}

L1-052. 2018我们要赢

题目:
2018年天梯赛的注册邀请码是“2018wmyy”,意思就是“2018我们要赢”。本题就请你用汉语拼音输出这句话。

输入格式:

本题没有输入。

输出格式:

在第一行中输出:“2018”;第二行中输出:“wo3 men2 yao4 ying2 !”。
输入样例:

本题没有输入。

输出样例:

2018
wo3 men2 yao4 ying2 !
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
   cout << "2018" << endl;
   cout << "wo3 men2 yao4 ying2 !" << endl;

}

L1-053. 电子汪

题目:
据说汪星人的智商能达到人类4岁儿童的水平,更有些聪明汪会做加法计算。比如你在地上放两堆小球,分别有1只球和2只球,聪明汪就会用“汪!汪!汪!”表示12的结果是3。

本题要求你为电子宠物汪做一个模拟程序,根据电子眼识别出的两堆小球的个数,计算出和,并且用汪星人的叫声给出答案。

输入格式:

输入在一行中给出两个[1, 9]区间内的正整数A和B,用空格分隔。

输出格式:

在一行中输出A+B个“Wang!”。
输入样例:

2 1

输出样例:

Wang!Wang!Wang!


代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b;
    cin >> a >> b;
    int n = a + b;
    while(n --)
    {
        cout <<"Wang!";
    }
    cout <<endl;
    return 0;
}

L1-054. 福到了

题意:
代码如下:


“福”字倒着贴,寓意“福到”。不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N x N 的网格组成的,网格中的元素或者为字符“@”或者为空格。而倒过来的汉字所用的字符由裁判指定。

输入格式:

输入在第一行中给出倒过来的汉字所用的字符、以及网格的规模 N (不超过100的正整数),其间以 1 个空格分隔;随后 N 行,每行给出 N 个字符,或者为“@”或者为空格。

输出格式:

输出倒置的网格,如样例所示。但是,如果这个字正过来倒过去是一样的,就先输出“bu yong dao le”,然后再用输入指定的字符将其输出。
输入样例 1$ 9
 @  @@@@@
@@@  @@@ 
 @   @ @ 
@@@  @@@ 
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
 @  @ @ @
 @  @@@@@

输出样例 1$$$$$  $ 
$ $ $  $ 
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
 $$$  $$$
 $ $   $ 
 $$$  $$$
$$$$$  $ 

输入样例 2:

& 3
@@@
 @ 
@@@

输出样例 2:

bu yong dao le
&&&
 & 
&&&

解析:此题那gets录入字符串可以正确得分,但是按照一个一个读入就会有一个数据错误。暴力求解就好
代码:
#include<iostream>
#include<string>
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char a;
    int n;
    bool flag = true;
    scanf("%c",&a);
    cin >> n;
    getchar();
    char mp[105][105];
    for(int i = 0; i<n; i ++)
    {
        gets(mp[i]);


    }
    for(int i =0,j = n - 1;i < n,j >= 0;i ++,j --)
    {
        if(strcmp(mp[i],mp[j]) == 0) {flag = true;}
        else {flag = false; break;}
        cout << flag << endl;
    }
    for(int i =0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(mp[i][j] == '@')
                mp[i][j] = a;
        }
    }

    int cnt_x=n-1,cnt_y=n-1;
    for(int i = 0; i < n; i ++)
    {
        cnt_y=n-1;
        for(int j = 0; j < n; j ++)
        {
             if(mp[i][j] != mp[cnt_x][cnt_y--])
            {
                flag = false;
                break;
            }
        }
         cnt_x --;
            if(flag == false)
                break;
    }
    if(flag == true )
        cout << "bu yong dao le" << endl;
    for(int i = n - 1; i >=0; i --)
    {
        for(int j = n - 1; j >= 0; j --)
        {
            printf("%c",mp[i][j]);
        }
        cout <<endl;
    }
    return 0;
}

L1-055. 谁是赢家

题目:


某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和3名评委投票两部分共同决定。规则为:如果一位艺人的观众票数高,且得到至少1名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。节目保证投票的观众人数为奇数,所以不存在平票的情况。本题就请你用程序判断谁是赢家。

输入格式:

输入第一行给出 2 个不超过 1000 的正整数 Pa 和 Pb,分别是艺人 a 和艺人 b 得到的观众票数。题目保证这两个数字不相等。随后第二行给出 3 名评委的投票结果。数字 0 代表投票给 a,数字 1 代表投票给 b,其间以一个空格分隔。

输出格式:

按以下格式输出赢家:

The winner is x: P1 + P2

其中 x 是代表赢家的字母,P1 是赢家得到的观众票数,P2 是赢家得到的评委票数。
输入样例:

327 129
1 0 1

输出样例:

The winner is a: 327 + 1


代码如下:
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cstring>
using namespace std;
int main()
{
    int a,b;
    int x, y, z;
    int a1=0,b1=0;
    cin>>a>>b>>x>>y>>z;
    if(x==0) a1++;
    else    b1++;
    if(y==0) a1++;
    else    b1++;
    if(z==0) a1++;
    else    b1++;
    if(a1==3)
        printf("The winner is a: %d + %d\n",a,a1);
    else if(a1==0)
        printf("The winner is b: %d + %d\n",b,b1);
    else if(a>b)
        printf("The winner is a: %d + %d\n",a,a1);
    else
        printf("The winner is b: %d + %d\n",b,b1);
    return 0;
}

L1-056. 猜数字

题目:
一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。

输入格式:

输入在第一行给出一个正整数N(<= 104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(<= 100)。

输出格式:

在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。
输入样例:

7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62

输出样例:

22 Amy
解析:
开一个结构体,然后按照题意求解。
代码:
#include<bits/stdc++.h>
#include<limits>
using namespace std;
struct node
{
    string str;
    int num;
}a[10000];
int main()
{
    int n;
    cin >> n;
    double  sum = 0;
    for(int i = 0;i < n;i ++)
    {
        cin >>a[i].str >>a[i].num;
        sum += a[i].num;

    }
    sum = sum / (2 * n);
    int maxx = INT_MAX;
    int id;
    string s;
    for(int i = 0;i < n;i ++)
    {
        if(abs(a[i].num - sum) <= maxx)
        {
            id = a[i].num;
            s = a[i].str;
            maxx = abs(a[i].num - sum);
        }


    } cout << (int)sum << " " << s << endl;
    return 0;
}

L2-025. 分而治之

题目:


分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。

输入格式:

输入在第一行给出两个正整数 N 和 M(均不超过10 000),分别为敌方城市个数(于是默认城市从 1 到 N 编号)和连接两城市的通路条数。随后 M 行,每行给出一条通路所连接的两个城市的编号,其间以一个空格分隔。在城市信息之后给出参谋部的系列方案,即一个正整数 K (<= 100)和随后的 K 行方案,每行按以下格式给出:

Np v[1] v[2] ... v[Np]

其中 Np 是该方案中计划攻下的城市数量,后面的系列 v[i] 是计划攻下的城市编号。

输出格式:

对每一套方案,如果可行就输出“YES”,否则输出“NO”。
输入样例:

10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 10
2 4
5
4 10 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2

输出样例:

NO
YES
YES
NO
NO
解析:
开一个二维数组用来存连通路,然后把要攻击的城镇存到一个集合里面,查找如果有任意一个点通路那么该方案为很差方案。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int mp[10005][2];
set<int>se;
int main()
{
    int n,m,k;
    int x;
    int t;
    cin >> n >> m;
    for(int i = 0; i < m; i ++)
        cin>>mp[i][0]>>mp[i][1];
    cin>>k;
    while(k--)
    {   bool flag = true;
        cin >> t;
        for(int i = 0; i< t; i ++)
        {
            cin >> x;
            se.insert(x);///将攻击城市存入进去
        }
        for(int i = 0; i < m; i ++)
        {
            if(se.find(mp[i][0])==se.end()&&se.find(mp[i][1])==se.end())///查找两座城市是否有通路当有通路的时候直接退出输出结果
            {
                flag = false;
                break;
            }
        }
        if(flag == false)
            cout << "NO" << endl;
        else
            cout << "YES" << endl;
            se.clear();
    }

    return 0;
}

L2-026. 小字辈

题目:

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。

输入格式:

输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。

输出格式:

首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。
输入样例:

9
2 6 5 5 -1 5 6 4 7

输出样例:

4
1 9


解析:
 可知这是树,那么我们可以用二维动态数组存入来构建之间的关系,然后dfs遍历查找最小的后代。最后用一个优先队列维护一下。

代码:
#include<bits/stdc++.h>
using namespace std;
vector<int>ve[100005];
int cnt = 1;
int maxx = -1;
struct cmp
{
    bool operator() (int x,int y)
    {
        return x > y;
    }
};
priority_queue<int,vector<int>,cmp>q;
void dfs(int id)
{

    if(ve[id].size() == 0)
    {
        if(cnt > maxx)
        {
            while(!q.empty())
            {
                q.pop();
            }
            q.push(id);
        }
        else if (cnt == maxx)
        {
            q.push(id);
        }
        maxx = max(cnt,maxx);
    }
    else
    {
        for(int i = 0; i < ve[id].size(); i ++)
        {
            cnt ++;
            dfs(ve[id][i]);
            cnt --;
        }
    }

}
int main()
{
    int n,m;
    int id;
    cin >> n;

    for(int i = 1; i <= n; i ++)
    {
        cin >> m;
        if(m == -1)
        {
            id = i;
            continue;
        }
        else
        {
            ve[m].push_back(i);//存儿砸 m 是上一代
        }
    }
    dfs(id);
    cout << maxx << endl;
    if(!q.empty())
    {
        cout << q.top();
        q.pop();
    }
    while(!q.empty())
    {
        cout << " " <<q.top();
        q.pop();
    }
    return 0;
}

L2-027. 名人堂与代金券

题目:


对于在中国大学MOOC(http://www.icourse163.org/)学习“数据结构”课程的学生,想要获得一张合格证书,总评成绩必须达到 60 分及以上,并且有另加福利:总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G) 区间内者,可以得到 20 元PAT代金券。全国考点通用,一年有效。同时任课老师还会把总评成绩前 K 名的学生列入课程“名人堂”。本题就请你编写程序,帮助老师列出名人堂的学生,并统计一共发出了面值多少元的 PAT 代金券。

输入格式:

输入在第一行给出 3 个整数,分别是 N(不超过 10 000 的正整数,为学生总数)、G(在 (60,100) 区间内的整数,为题面中描述的代金券等级分界线)、K(不超过 100 且不超过 N 的正整数,为进入名人堂的最低名次)。接下来 N 行,每行给出一位学生的账号(长度不超过15位、不带空格的字符串)和总评成绩(区间 [0, 100] 内的整数),其间以空格分隔。题目保证没有重复的账号。

输出格式:

首先在一行中输出发出的 PAT 代金券的总面值。然后按总评成绩非升序输出进入名人堂的学生的名次、账号和成绩,其间以 1 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。
输入样例:

10 80 5
cy@zju.edu.cn 78
cy@pat-edu.com 87
1001@qq.com 65
uh-oh@163.com 96
test@126.com 39
anyone@qq.com 87
zoe@mit.edu 80
jack@ucla.edu 88
bob@cmu.edu 80
ken@163.com 70

输出样例:

360
1 uh-oh@163.com 96
2 jack@ucla.edu 88
3 anyone@qq.com 87
3 cy@pat-edu.com 87
5 bob@cmu.edu 80
5 zoe@mit.edu 80

题解:定义结构体,方便操作,注意点有两个:
1.在有并列排名的时候,按账号的字母升序输出,如果账号的第一位字母相同,那么就看第二位,第二位相同就看第三位,直到账号的字母不同(升序)
2.给学生编id的时候,注意如果有两个第3名,那么接下来是没有第四名的,只有第五名
在编学生的id的时候,不能只编n个人的id,虽然只有n个学生,要把n放大到至少n+1
如下样例可以说明
11 80 5
cy@zju.edu.cn 99
cy@pat-edu.com 99
1001@qq.com 99
uh-oh@163.com 99
test@126.com 99
anyone@qq.com 99
zoe@mit.edu 99
jack@ucla.edu 99
bob@cmu.edu 99
ken@163.com 99
jiangyilong@163.com 99

代码如下:
#include<bits/stdc++.h>
using namespace std;
struct node
{
    string zh;
    int df;
    int id;

}a[100000];
bool cmp(node a,node b)
{
    if(a.df == b.df)
    {
        return a.zh.compare(b.zh) < 0;
    }
    return a.df > b.df;
}
int main()
{
    int n,g,k;
    int ans = 0;
    cin >> n >> g >> k;
    for(int i = 0;i < n;i ++)
    {
        cin >> a[i].zh >> a[i].df;
        if(a[i].df >= g) ans += 50;
        else if(a[i].df >= 60) ans += 20;
    }

    sort(a,a+n,cmp);
     a[0].id = 1;
    for(int i = 1;i < n;i ++)
    {
        if(a[i].df == a[i - 1].df) a[i].id = a[i - 1].id;
        else a[i].id = i+1;
    }
    cout << ans << endl;
    for(int i = 0;a[i].id <=k;i ++)
    {
        if(i >= n) return 0;
        else
        cout << a[i].id << " " << a[i].zh << " " << a[i].df << endl;
    }
    return 0;
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值