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
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; icin >> 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(题目让输出的那个数)这样不就找到他正着对应的数字了嘛。然后每次除以基数。求求出相应结果啦
代码如下:
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
#include
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
#include
using namespace std;
int main()
{
cout << "2018" << endl;
cout << "wo3 men2 yao4 ying2 !" << endl;
}
L1-053. 电子汪
题目:
据说汪星人的智商能达到人类4岁儿童的水平,更有些聪明汪会做加法计算。比如你在地上放两堆小球,分别有1只球和2只球,聪明汪就会用“汪!汪!汪!”表示1加2的结果是3。
本题要求你为电子宠物汪做一个模拟程序,根据电子眼识别出的两堆小球的个数,计算出和,并且用汪星人的叫声给出答案。
输入格式:
输入在一行中给出两个[1, 9]区间内的正整数A和B,用空格分隔。
输出格式:
在一行中输出A+B个“Wang!”。
输入样例:
2 1
输出样例:
Wang!Wang!Wang!
代码如下:
#include
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
int n = a + b;
while(n --)
{
cout <<"Wang!";
}
cout <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录入字符串可以正确得分,但是按照一个一个读入就会有一个数据错误。暴力求解就好
代码:
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; ifor(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 <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
#include
#include
#include
#include
#include
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
#include
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
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
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);
}
}
dfs(id);
cout << maxx << endl;
if(!q.empty())
{
cout << q.top();
q.pop();
}
while(!q.empty())
{
cout << " " <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
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
{
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
{
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
{
if(i >= n) return 0
else
cout << a[i].id << " " << a[i].zh << " " << a[i].df << endl
}
return 0
}