L1-1 天梯赛座位分配 (20 分)(待补)
题意:
天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位参赛选手。令每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后。从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员…… 以此类推。如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。本题就要求你编写程序,自动为各校生成队员的座位号,从 1 开始编号。
思路:
代码:
L1-2 倒数第N个字符串 (15 分)
题意:
给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz }。这个序列的倒数第27个字符串就是 zyz。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
思路:
正解的思路应该是先求字符串所有的种类数,再减去x,就能得到第x大的字符串然后使用26进制的转换,模拟时,我用暴力模拟不停的开个vector放字符串输出,会扣三分。
代码:
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
int main()
{
int l,r,i,x,j;
cin>>l>>x;
int d1=pow(26,l)-x;;
string s1;
vector<char >ans;
while(d1!=0)
{
int x;
x=d1%26;
d1/=26;
ans.push_back(x+'a');
}
reverse(ans.begin(),ans.end());
for(auto x:ans) cout<<x;
cout<<endl;
return 0;
}
L1-3 打折 (5 分)
题意:
去商场淘打折商品时,计算打折以后的价钱是件颇费脑子的事情。例如原价 ¥988,标明打 7 折,则折扣价应该是 ¥988 x 70% = ¥691.60。本题就请你写个程序替客户计算折扣价。
思路:
简单题直接输出
#include<bits/stdc++.h>
using namespace std;
int main()
{
double n,x;
cin>>n>>x;
cout<<fixed<<setprecision(2)<<(n*x*0.1)<<endl;
}
L1-4 2018我们要赢 (5 分)
题意:
2018年天梯赛的注册邀请码是“2018wmyy”,意思就是“2018我们要赢”。本题就请你用汉语拼音输出这句话。
思路:
直接输出即可
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<"2018\nwo3 men2 yao4 ying2 !"<<endl;
}
L1-5 电子汪 (10 分)
题意:
据说汪星人的智商能达到人类 4 岁儿童的水平,更有些聪明汪会做加法计算。比如你在地上放两堆小球,分别有 1 只球和 2 只球,聪明汪就会用“汪!汪!汪!”表示 1 加 2 的结果是 3。
本题要求你为电子宠物汪做一个模拟程序,根据电子眼识别出的两堆小球的个数,计算出和,并且用汪星人的叫声给出答案。
思路:
直接输出a+b次狗叫就行
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
for(int i=0;i<a+b;i++)cout<<"Wang!";
}
L1-6 福到了 (15 分)
题意:
“福”字倒着贴,寓意“福到”。不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @
或者为空格。而倒过来的汉字所用的字符由裁判指定。
思路:
输入按许顺入就行,输出的时候留一下,先倒着存好然后进行比较,相同就输出"bu yon dao le",具体就看代码吧。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
char m1[maxn][maxn],m2[maxn][maxn];
int n,m;
bool check()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(m1[i][j]!=m2[i][j]) return false;
}
return true;
}
int main()
{
char x;
int i,j,d;
cin>>x>>n;(m=n);
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
m1[i][j]=getchar();
}
getchar();
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
m2[i][j]=m1[n-i+1][n-j+1];
}
}
if(check())
{
cout<<"bu yong dao le"<<endl;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(m2[i][j]!=' ')
{
cout<<x;
}
else
{
cout<<' ';
}
}
cout<<endl;
}
}
L1-7 谁是赢家 (10 分)
题意:
某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和 3 名评委投票两部分共同决定。规则为:如果一位艺人的观众票数高,且得到至少 1 名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。节目保证投票的观众人数为奇数,所以不存在平票的情况。本题就请你用程序判断谁是赢家。
思路:
稍微判断一下,对着题意模拟即可,判断其中一人赢需要的条件,然后else输出一下即可
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int pa,pb;
int d1,d2,d3;
cin>>pa>>pb;
cin>>d1>>d2>>d3;
if(d1+d2+d3==0||(d1+d2+d3!=3)&&pa>pb)
{
cout<<"The winner is a: "<<pa<<" + "<<3-(d1+d2+d3)<<endl;
}
else
{
cout<<"The winner is b: "<<pb<<" + "<<(d1+d2+d3)<<endl;
}
return 0;
}
L1-8 猜数字 (20 分)
题意:
一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。
思路:
题目要求其实可以提出来,假设第i个人猜的数为ai,且所有人的数字之和为sum,那么本质就是找找对于每个i,找的最小值,这里我怕精度,于是直接转
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node {
string name;
int val;
}mo[maxn];
bool cmp1(node a,node b )
{
return a.val<b.val;
}
int main()
{
int n,i,j,t,sum=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>mo[i].name>>mo[i].val;
sum+=mo[i].val;
}
for(i=0;i<n;i++)
{
mo[i].val=abs(sum-mo[i].val*2*n);
}
sort(mo,mo+n,cmp1);
cout<<(int)(sum/(n*2))<<" "<<mo[0].name<<endl;
return 0;
}
L2-1 分而治之 (25 分)
题意:
分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。
输入:
输入在第一行给出两个正整数 N 和 M(均不超过10 000),分别为敌方城市个数(于是默认城市从 1 到 N 编号)和连接两城市的通路条数。随后 M 行,每行给出一条通路所连接的两个城市的编号,其间以一个空格分隔。在城市信息之后给出参谋部的系列方案,即一个正整数 K (≤ 100)和随后的 K 行方案,每行按以下格式给出:
Np v[1] v[2] ... v[Np]
其中 Np
是该方案中计划攻下的城市数量,后面的系列 v[i]
是计划攻下的城市编号。
输出:
对每一套方案,如果可行就输出YES
,否则输出NO
。
思路:
一开始读题读错了,一定要注意他题意其实是说,把方案数里的所有城市关闭,那么剩下的城市是否能全部被孤立,孤立就是说没有和其他城市相连,那么其实你按照题意把树建好之后,将攻下的城市打下标机,然后每个点遍历,只要有一个点能去往其他城市,直接输出NO。
代码:
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
const int maxn=10005;
int N,M;
vector<int >edges[maxn];
int main()
{
int i,j;
cin>>N>>M;
for(i=0;i<M;i++)
{
int a,b;
cin>>a>>b;
edges[a].push_back(b);
edges[b].push_back(a);
}
int k;
cin>>k;
unordered_map<int ,int >mo;
while(k--)
{
int d,flag=0;
cin>>d;
vector<int> qry(d);
for(int &i:qry ){
cin>>i;
mo[i]=1;
}
for(i=1;i<=N;i++)
{
if(mo[i]==0)
{
for(j=0;j<edges[i].size();j++)
{
if(mo[edges[i][j]]==0) {
flag=1;
cout<<"NO"<<endl;
break;
}
}
}
if(flag==1) break;
}
if(flag==0){
cout<<"YES"<<endl;
}
mo.clear();
}
return 0;
}
L2-2 小字辈 (25 分)
题意:
输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。
思路:
把成员和父母之间的关系连边建好,对于每个i来说a[i]就是父节点,i就是子节点,-1就是源头,然后从源头开始bfs,对每个边打上深度标机,然后找深度最大的再输出即可。
代码:
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
const int maxn=100005;
int a[maxn];
int main()
{
int n,i,j,t;
cin>>n;
vector<int >edges[n];
for(i=0;i<=n;i++) {
edges[i].clear();
}
for(i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]==-1) a[i]=0;
edges[a[i]].push_back(i);
}
deque<int >qq;
qq.push_back(0);
unordered_map<int ,int >mo;
mo[0]=1;
int ans=1;
while(!qq.empty())
{
int d1=qq.front();
qq.pop_front();
for(i=0;i<edges[d1].size();i++)
{
if(mo[edges[d1][i]]==0)
{
mo[edges[d1][i]]=mo[d1]+1;
qq.push_back(edges[d1][i]);
ans=max(ans,mo[d1]+1);
}
}
}
cout<<ans-1<<endl;
vector<int >ans1;
for(auto &[a,b]:mo)
{
if(b==ans)
{
ans1.push_back(a);
}
}
sort(ans1.begin(),ans1.end());
for(i=0;i<ans1.size()-1;i++) cout<<ans1[i]<<" ";
cout<<ans1[i]<<endl;
}
L2-3 名人堂与代金券 (25 分)
题意:
对于在中国大学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 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。
思路:
非常简单的一道题,直接一个结构体排序重载一下即可。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
const int maxn=10005;
struct node{
string s1;
int val;
}mo[maxn];
bool cmp1(node a,node b )
{
return a.val<b.val;
}
int main()
{
int n,g,k,sum=0,i,j;
cin>>n>>g>>k;
for(i=0;i<n;i++)
{
cin>>mo[i].s1>>mo[i].val;
if(mo[i].val>=60&&mo[i].val<g)
sum+=20;
else if(mo[i].val>=g)
sum+=50;
}
cout<<sum<<endl;
sort(mo,mo+n,cmp1);
for(i=1;i<=n;i++)
{
if(mo[i].val<=mo[k].val)
cout<<i<<" "<<mo[i].s1<<" "<<mo[i].val<<endl;
else
break;
}
return 0;
}