2020年HZNU天梯训练赛 Round 7

2020年HZNU天梯训练赛 Round 7

时间:2020.7.23 12 170

完成情况:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

√ 当场做出来 ※做了一半来 ✘补题补出来

7-1 天梯赛座位分配 (20分)

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 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
#include<bits/stdc++.h>
using namespace std;
//用二维数组第二位与10的关系将三维数组化简为二维 
int a[102][102],b[102][102];
int main()
{
	int n,m,maxx=0,x=1,y=-1;
	cin>>n;
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	for(int i=0;i<n;i++)
	{
		cin>>m;maxx=m>maxx?m:maxx;
		for(int j=0;j<10*m;j++)a[i][j]=1;//标记一下总座位数 
	}
	for(int i=0;i<10*maxx;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(a[j][i])
			{  
				if(y!=j) b[j][i]=x++,y=j;
				else{x+=1;b[j][i]=x++;y=j;}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		cout<<"#"<<i<<endl;
		for(int j=0;j<10*maxx;j++)
		{
		
			if(b[i-1][j])
			{
				cout<<b[i-1][j];
				if((j+1)%10!=0)cout<<" ";
				else if((j+1)%10==0)cout<<endl;
			} 
			//if(b[i][j])printf("%d%c",b[i][j],(j+1)%10==0?'\n':' '); 
		}
	}
	return 0;
}
/*#include<bits/stdc++.h>//错误原因 当一所学校编完了就不再编所以还需要记录 
using namespace std;
int main()
{
	int n,m,x;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>m;x=i;
		cout<<"#"<<x<<endl;
		for(int j=0;j<m;j++)
		{
			for(int k=0;k<10;k++)
			{	
				cout<<x;
				if(k!=9)cout<<" ";
				x+=n;
			}
			cout<<endl;
		}
	}
	return 0;
}*/

7-2 倒数第N个字符串 (15分)

给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 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
#include<bits/stdc++.h>
using namespace std;
char s[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int main()
{
	int L,N,flag;
	char ans[6];
	cin>>L>>N;
	for(int i=1;i<=L;i++)
	{
		flag=0;
		if(i==1)
		{
			if(N%26==0){ans[L-i]=s[0];N=N/26-1;flag=1;}
			else  ans[L-i]=s[26-N%26];
		}
		else ans[L-i]=s[26-N%26-1];
		if(flag==0)N=N/26;
	}
	cout<<ans;
	return 0;
}

7-3 打折 (5分)

去商场淘打折商品时,计算打折以后的价钱是件颇费脑子的事情。例如原价 ¥988,标明打 7 折,则折扣价应该是 ¥988 x 70% = ¥691.60。本题就请你写个程序替客户计算折扣价。

输入格式:

输入在一行中给出商品的原价(不超过1万元的正整数)和折扣(为[1, 9]区间内的整数),其间以空格分隔。

输出格式:

在一行中输出商品的折扣价,保留小数点后 2 位。

输入样例:

988 7

输出样例:

691.60
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a,b;
	cin>>a>>b;
	printf("%.2lf",1.0*a*b/10);
	return 0; 
} 

7-4 2018我们要赢 (5分)

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

输入格式:

本题没有输入。

输出格式:

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

输入样例:

本题没有输入。

输出样例:

2018
wo3 men2 yao4 ying2 !
2018
wo3 men2 yao4 ying2 !

7-5 电子汪 (10分)

据说汪星人的智商能达到人类 4 岁儿童的水平,更有些聪明汪会做加法计算。比如你在地上放两堆小球,分别有 1 只球和 2 只球,聪明汪就会用“汪!汪!汪!”表示 1 加 2 的结果是 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;
	for(int i=0;i<a+b;i++)
		cout<<"Wang!";
	return 0; 
} 

7-6 福到了 (15分)

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

输入格式:

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

输出格式:

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

输入样例 1:

$ 9
 @  @@@@@
@@@  @@@ 
 @   @ @ 
@@@  @@@ 
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
 @  @ @ @
 @  @@@@@

输出样例 1:

$$$$$  $ 
$ $ $  $ 
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
 $$$  $$$
 $ $   $ 
 $$$  $$$
$$$$$  $ 

输入样例 2:

& 3
@@@
 @ 
@@@

输出样例 2:

bu yong dao le
&&&
 & 
&&&
#include<bits/stdc++.h>
using namespace std;
string s[101];
int main()
{
	int n,flag=0;
	char c;
	cin>>c>>n;
	//cout<<c<<n; 
	getchar();
	for(int i=0;i<n;i++) 
	{
		getline(cin,s[i]);
		//for(int j=0;j<n;j++)
		//	scanf("%c",s[i][j]);
		//getchar();
	}
	//cout<<s[0][0];
	//cin.getline(s[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(s[i][j]!=' ') s[i][j]=c;
			else s[i][j]=' ';
		}
	}
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			if(s[i][j]!=s[n-i-1][n-j-1])flag=1;
	if(flag==0)cout<<"bu yong dao le"<<endl;
	for(int i=n-1;i>=0;i--)
	{
		for(int j=n-1;j>=0;j--)
			cout<<s[i][j];
		cout<<endl;
	}
	return 0;
}

7-7 谁是赢家 (10分)

某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和 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<bits/stdc++.h>
using namespace std;
int main()
{
	int a,b,x,cnt=0;
	cin>>a>>b;
	for(int i=0;i<3;i++)
	{
		cin>>x;
		if(x==1)cnt++;
	}
	if((a>b&&cnt!=3)||(cnt==0))cout<<"The winner is a: "<<a<<" + "<<3-cnt;
	else cout<<"The winner is b: "<<b<<" + "<<cnt;
	return 0; 
} 

7-8 猜数字 (20分)

一群人坐在一起,每人猜一个 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>
using namespace std;
struct node {char name[10];int n;}id[10005];//名字开8会卡测试点2、3??? 
int main()
{
	int n,sum=0,aver,minn=200,mini=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>id[i].name>>id[i].n;
		sum+=id[i].n;
	}
	aver=sum/n/2;
	for(int i=0;i<n;i++)
	{
		if(abs(aver-id[i].n)<minn){minn=abs(aver-id[i].n);mini=i;}
	}
	cout<<aver<<" "<<id[mini].name;
	return 0;
}

7-9 分而治之 (25分)

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

输入格式:

输入在第一行给出两个正整数 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;
vector<int> v[10005];
//无向图的连通 
int main()
{
	int n,m,a,b,k,y,z,flag,c[10005];
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		cin>>a>>b;
		v[a].push_back(b);
		v[b].push_back(a);
	} 
	cin>>k;
	while(k--)
	{
		memset(c,0,sizeof(c));flag=0;
		cin>>y;
		while(y--){cin>>z;c[z]=1;}
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<v[i].size();j++)
			{
				if(c[i]==0&&c[v[i][j]]==0){flag=1;break;}
			}
		}
		if(flag==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	} 
	return 0; 
}

7-10 小字辈 (25分)

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

输入格式:

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

输出格式:

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

输入样例:

9
2 6 5 5 -1 5 6 4 7

输出样例:

4
1 9
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn],b[maxn];
int f(int x)
{
    if(a[x]==-1)return b[x]=1;
	if(b[x])	return b[x];
    else 		return b[x]=f(a[x])+1;
}
int main()
{
    int n,minn=0,flag=1;
    cin>>n;
    for(int i=1;i<=n;i++)a[i]=i;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)minn=f(i)>minn?f(i):minn;
    cout<<minn<<endl;
    for(int i=1;i<=n;i++)
    {
    	if(b[i]==minn)
    	{
        	if(flag)  {cout<<i;flag=0;}
        	else   	  cout<<" "<<i;
    	}
    }
	return 0;
}

7-11 名人堂与代金券 (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 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。

输入样例:

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
#include <bits/stdc++.h>
using namespace std;
//≈点赞狂魔 
struct node{string name;int score;}id[10005];
bool comp(node a, node b)
{
	if(a.score != b.score) return a.score > b.score;
	else return a.name < b.name;
}
int main()
{
	int n,g,k,sum=0;
	cin>>n>>g>>k;
	for(int i=0;i<n;i++)
	{
		cin>>id[i].name>>id[i].score;
		if(id[i].score>=g) sum+=50;
		else if(id[i].score>=60) sum+=20;
	}
	cout<<sum<<endl;
	sort(id,id+n,comp);
	int cnt;
	for(int i=1;i<n;i++)
	{
		if(i==1||id[i-1].score !=id[i-2].score){cnt=i;if(cnt>k) break;cout<<i;}
		else cout<<cnt;
		cout<<" "<<id[i-1].name<<" "<<id[i-1].score<<endl;
	}
	return 0;
}

7-12 秀恩爱分得快 (25分)

古人云:秀恩爱,分得快。

互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 K 个人,这些人两两间的亲密度就被定义为 1/K。任意两个人如果同时出现在若干张照片里,他们之间的亲密度就是所有这些同框照片对应的亲密度之和。下面给定一批照片,请你分析一对给定的情侣,看看他们分别有没有亲密度更高的异性朋友?

输入格式:

输入在第一行给出 2 个正整数:N(不超过1000,为总人数——简单起见,我们把所有人从 0 到 N-1 编号。为了区分性别,我们用编号前的负号表示女性)和 M(不超过1000,为照片总数)。随后 M 行,每行给出一张照片的信息,格式如下:

K P[1] ... P[K]

其中 K(≤ 500)是该照片中出现的人数,P[1] ~ P[K] 就是这些人的编号。最后一行给出一对异性情侣的编号 A 和 B。同行数字以空格分隔。题目保证每个人只有一个性别,并且不会在同一张照片里出现多次。

输出格式:

首先输出 A PA,其中 PA 是与 A 最亲密的异性。如果 PA 不唯一,则按他们编号的绝对值递增输出;然后类似地输出 B PB。但如果 AB 正是彼此亲密度最高的一对,则只输出他们的编号,无论是否还有其他人并列。

输入样例 1:

10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2

输出样例 1:

-3 2
2 -5
2 -6

输入样例 2:

4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2 
-3 2

输出样例 2:

-3 2

7-13 代码排版 (30分)

某编程大赛中设计有一个挑战环节,选手可以查看其他选手的代码,发现错误后,提交一组测试数据将对手挑落马下。为了减小被挑战的几率,有些选手会故意将代码写得很难看懂,比如把所有回车去掉,提交所有内容都在一行的程序,令挑战者望而生畏。

为了对付这种选手,现请你编写一个代码排版程序,将写成一行的程序重新排版。当然要写一个完美的排版程序可太难了,这里只简单地要求处理C语言里的for、while、if-else这三种特殊结构,而将其他所有句子都当成顺序执行的语句处理。输出的要求如下:

  • 默认程序起始没有缩进;每一级缩进是 2 个空格;
  • 每行开头除了规定的缩进空格外,不输出多余的空格;
  • 顺序执行的程序体是以分号“;”结尾的,遇到分号就换行;
  • 在一对大括号“{”和“}”中的程序体输出时,两端的大括号单独占一行,内部程序体每行加一级缩进,即:
{
  程序体
}
  • for的格式为:
for (条件) {
  程序体
}
  • while的格式为:
while (条件) {
  程序体
}
  • if-else的格式为:
if (条件) {
  程序体
}
else {
  程序体
}

输入格式:

输入在一行中给出不超过 331 个字符的非空字符串,以回车结束。题目保证输入的是一个语法正确、可以正常编译运行的 main 函数模块。

输出格式:

按题面要求的格式,输出排版后的程序。

输入样例:

int main()  {int n, i;  scanf("%d", &n);if( n>0)n++;else if (n<0) n--; else while(n<10)n++; for(i=0;  i<n; i++ ){ printf("n=%d\n", n);}return  0; }

输出样例:

int main()
{
  int n, i;
  scanf("%d", &n);
  if ( n>0) {
    n++;
  }
  else {
    if (n<0) {
      n--;
    }
    else {
      while (n<10) {
        n++;
      }
    }
  }
  for (i=0;  i<n; i++ ) {
    printf("n=%d\n", n);
  }
  return  0;
}

7-14 至多删三个字符 (35分)

给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串?

输入格式:

输入在一行中给出全部由小写英文字母组成的、长度在区间 [4, 106] 内的字符串。

输出格式:

在一行中输出至多删掉其中 3 个字符后不同字符串的个数。

输入样例:

ababcc

输出样例:

25

提示:

删掉 0 个字符得到 "ababcc"。

删掉 1 个字符得到 "babcc", "aabcc", "abbcc", "abacc" 和 "ababc"。

删掉 2 个字符得到 "abcc", "bbcc", "bacc", "babc", "aacc", "aabc", "abbc", "abac" 和 "abab"。

删掉 3 个字符得到 "abc", "bcc", "acc", "bbc", "bac", "bab", "aac", "aab", "abb" 和 "aba"。


7-15 神坛 (30分)

在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好。特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面积为 0.000

长老们发现这个问题没有那么简单,于是委托你编程解决这个难题。

输入格式:

输入在第一行给出一个正整数 n(3 ≤ n ≤ 5000)。随后 n 行,每行有两个整数,分别表示神石的横坐标、纵坐标(−109≤ 横坐标、纵坐标 <109)。

输出格式:

在一行中输出神坛的最小面积,四舍五入保留 3 位小数。

输入样例:

8
3 4
2 4
1 1
4 1
0 3
3 0
1 3
4 2

输出样例:

0.500

样例解释

输出的数值等于图中红色或紫色框线的三角形的面积。

altar.JPG


posted @ 2020-07-24 09:06  神奇周一  阅读(331)  评论(0编辑  收藏  举报