2018-2019赛季多校联合新生训练赛第二场题解和补题

这场比赛还是铜牌…虽然说只是一个铜牌(第66名),但是已经这也是相当努力之后的结果了 要想拉开差距就只能多做题呗 下面开始啦~
这题我从刚开始看到做到最后结束都没有做出来…
问题 A: 朋友

题目描述

同学们应该学会多交一些好朋友。朋友关系是相互的,A 是 B 的好朋友,则 B 也是 A 的好朋友。朋友关系是不传递的,A 是 B 的好朋友,B 是 C 的好朋友,但 A 和 C 不一定是好朋友。现在给出某小学部分同学之间的朋友关系,请编程统计朋友最多的人有多少个好朋友。

输入

输入共m+1行。
第1行是两个整数n和m,分别表示同学总人数和朋友关系对数。
第2行到第m+1行,描述了m对朋友关系。每行两个用单个空格隔开的同学姓名。
每个人的姓名仅由小写字母组成,且1≤姓名的长度≤10。

输出

输出共 1 行。
一个整数,表示朋友最多的人有多少个好朋友。

样例输入
复制样例数据 4 3
lucy lily
jam lily
jam peter

样例输出
2
提示

4个人,3对朋友关系。lucy只有一个朋友lily;jam有两个朋友lily和peter;lily有两个朋友lucy和jam;
peter只有一个朋友jam。
所以lily和jam朋友最多,都是2个。

50%以上的测试点输入数据保证朋友关系没有重复。
100%的测试点输入数据保证2≤n≤100,1≤m≤1000,且没有自己跟自己的朋友关系。

这题借鉴一下队里马大佬的map写法,因为实在是太妙了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!不惜破坏优美的排版也要大力吹这种方法(滑稽)
下面是神奇的map代码 真的是学到了 还有这种操作(map开二维string数组)

#include<bits/stdc++.h>
using namespace std;
int maxn=-9999999;
map<string,map<string,int> >ma;//开二维的string map 我只想说 tql!!!!
map<string,int>bk;//这里是习惯写法
int main() {
  int n,m;
  cin>>n>>m;
  string a,b;
  for(int i=0;i<m;i++) {
    cin>>a>>b;
    if(!ma[a][b]&&!ma[b][a]) {
      ma[a][b]=ma[b][a]=1;
      bk[a]++;
      bk[b]++;
    }//这里是提示中的自己和自己不能成为朋友还有朋友不能重复
    maxn=max(maxn,bk[a]);//比大小
    maxn=max(maxn,bk[b]);
  }
  cout<<maxn;
}

tql Orz
问题 B: 排队IV (这就是个神经病题目啊好不好!!!)

题目描述

在很多场合,我们都需要排队,比如超市付款,医院看病,就餐等等。“尊老爱幼”是中华名族的传统美德,所以在排队的过程中,遇到老人、幼儿我们应该主动让他们排在前面。请按以下 4 条规则编写一个排队的程序。
(1)老人(年龄 ≥ 60 岁)和幼儿(年龄 ≤ 6 岁)比其他人(6 岁 < 年龄 < 60 岁)优先排在队伍的前面,且所有幼儿排在所有老人的前面。
(2)老人按年龄从大到小的顺序排队,年龄大的优先,年龄相同时,先到的人排在前面。
(3)幼儿按年龄从小到大的顺序排队,年龄小的优先,年龄相同时,先到的人排在前面。
(4)其他人只按到达的先后顺序排队。

输入

输入共n+1行。
第1行一个整数n,表示排队的总人数。
第2行到第n+1行,按照到达的先后顺序给出了每个人的基本信息。每行两个整数,第一个整数表示这个人的编号(编号保证不会重复,但不保证连续),第二个整数表示这个人的年龄。

输出

输出共n行。
每行一个人的编号,表示从前往后的排队结果。

样例输入
复制样例数据 8
1 14
3 6
4 5
5 62
11 48
17 25
21 60
13 62

样例输出
4
3
5
13
21
1
11
17

提示

共有8个人参加排队。编号为3和4的两个人为幼儿,年龄分别为6岁和5岁。编号为5、21和13的三个人为老人,年龄分别为62岁、60岁和62岁。根据排队规则,老人和幼儿排在其他人的前面,而幼儿又排在老人的前面,所以先排编号3和4的幼儿。幼儿按年龄从小到大的顺序排队,所以第一个人是4号,然后是3号。接下来排老人,老人年龄大的先排,所以先排5号和13号,但5号比13号先到,所以先排5号,然后13号,接下来21号。剩下的人不论年龄大小,全部按到达的顺序排队,依次为1号、11号和17号。

【数据范围约定】
40%的测试点输入数据保证1≤n≤99,且每个人的年龄都不相同。
60%的测试点输入数据保证1≤n≤1000。
100%的测试点输入数据保证1≤n≤30000,1≤人的编号≤32000,2≤人的年龄≤100。

这题刚开始我以为是按序号排队,后来才反应过来原来是先来后到 = =! 恍然大悟以后a了这道题,交了7次终于a了= = 代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
  int id;
  int m;
  int a;
}a[100000];
bool cmp(node a,node b) {
  if(a.a<=6) {
    if(b.a<=6) {
      if(a.a==b.a)
      return a.id<b.id;
      else
      return a.a<b.a;
    }
    if(b.a>6&&b.a<60)
    return a.a<b.a;
    if(b.a>=60)
    return a.a<b.a;
  }
  else if(a.a>=60) {
    if(b.a>=60) {
      if(a.a==b.a)
      return a.id<b.id;
      else
      return a.a>b.a;
    }
    if(b.a>6&&b.a<60)
    return a.a>b.a;
    if(b.a<=6)
    return a.a<b.a;
  }
  else if(a.a>6&&a.a<60) {
    if(b.a<=6)
    return a.a<b.a;
    else if(b.a>6&&b.a<60)
    return a.id<b.id;
    else if(b.a>=60)
    return a.a>b.a;
  }
}
int main() {
  int n;
  cin>>n;
  for(int i=0;i<n;i++) {
    cin>>a[i].m>>a[i].a;
    a[i].id=i;
  }
  sort(a,a+n,cmp);
  for(int i=0;i<n;i++)
  cout<<a[i].m<<endl;
}

这里我用了结构体自定义排序,就算题目么问题 这也太麻烦了8!
问题 C: 爱好数学的国王

题目描述

Z 国的国王是一个非常爱好数学的国王。一天他对着他的那些大臣说:“素数真是一种神奇的正整数,除了1和它本身外,不能被其他任何正整数整除,2是最小的素数,有无穷多个啊……它还有一个美妙的名字:质数,……数学多么有趣啊……”。
Z 国今年风调雨顺,百姓丰衣足食。为了奖励他那帮管理有方的大臣,他决定把全部的 N 元奖金平均分配给其中的 K 位大臣,但酷爱数学的国王要求这 K 位大臣每人拿到的奖金必须是个素数。哪个大臣能够解决这个数学问题,国王就把奖金给这个大臣和另外的 K-1 人。
大臣们都想自己获得更多的奖金,所以希望分得奖金的大臣人数 K 越少越好。机智的大臣请来了“编程大侠”来帮忙解决这个问题。国王的间谍得知了这个情况后向国王汇报了大臣的行为。国王早就听说“编程大侠”的厉害,于是决定问 T 次这个问题,来试探一下
“编程大侠”的真正实力。

输入

输入共T+1行。
第1行一个整数T,表示国王问了T次。
接下来T行每行一个整数N,表示国王打算分配给大臣的总奖金。

输出

输出共T行。
第i行一个整数K,表示最少多少位大臣来平分输入中对应的全部奖金。如果找不到满足国王要求的分配办法,请输出“0”(输出时不包含双引号)。

样例输入
复制样例数据 3
3
4
100

样例输出
1
2
20

提示

国王共问了 3 次。
第一次国王说:“我们总共有 3 元奖金”。“编程大侠”说:“最少分配给 1 位大臣,他可以获得所有奖金,即 3 元,因为 3 是一个素数”。
第二次国王说:“我们总共有 4 元奖金”。“编程大侠”说:“最少分配给 2 位大臣,他们每人可以获得 2 元奖金,因为 2 是一个素数”。
第三次国王说:“我们总共有 100 元奖金”。“编程大侠”说:“最少分配给 20 位大臣,他们每人可以获得 5 元奖金,因为 5 是一个素数”。

50%的测试点输入数据保证 1≤T≤5,1≤N≤10000
70%的测试点输入数据保证 1≤T≤10,1≤N≤1000000000
100%的测试点输入数据保证 1≤T≤10,1≤N≤2000000000

此处无声胜有声(待解决2333)

问题 D: 修建高楼

题目描述

C 市有一条东西走向的“市河”。C 市的市长打算在“市河”的其中一条岸边自东往西的 n 个位置(可以将这 n 个位置看成在一条直线上,且位置不会重叠)依次建造高楼。
C 市的设计部门设计了 T 个方案供市长挑选(方案编号为 1 到 T)。每个方案都提供了建造的每幢高楼的高度,自东向西依次为 h1,h2,h3,…,hn-1,hn。每幢楼房的高度在 1 到 n 之间(包括 1 和 n),且各不相同。
市长在挑选设计方案时,喜欢 n 幢高楼中任意 3 幢(包括不连续的 3 幢)有一定的“梯度美”。所谓“梯度美”是指这 3 幢高楼满足:
第j幢的高度hj-第i幢的高度hi=第k幢的高度hk-第j幢的高度hj(1≤i<j<k≤n)
市长喜欢方案中这种“梯度美”现象越多越好。请编程帮市长挑选一下设计方案吧。

输入

T+1 行。
第一行两个整数 T 和 n,分别表示设计部门提供的方案总数和打算建造的高楼数。
接下来每一行表示一种方案。第 i+1 行表示第 i 种方案,每行 n 个整数,依次表示每幢高楼打算建造的高度。

输出

输出共 1 行。
包含两个整数,第一整数为出现“梯度美”次数最多的方案,第二个整数为对应方案“梯度美”出现的次数。如果出现“梯度美”次数最多的方案有多个,输出方案编号较小的方案。

样例输入
复制样例数据 2 5
3 1 2 4 5
3 1 2 5 4

样例输出
1 1

提示

输入中共有2个方案,打算建造5幢高楼。
第一个方案每幢高楼高度依次为3,1,2,4,5,其中第1幢,第4幢和第5幢高度出现“梯度美”(3,4,5),这3幢高楼的后一幢比前一幢依次高1。
第二个方案每幢高楼高度依次为3,1,2,5,4,没有出现“梯度美”。

50%的测试点输入数据保证 1≤T≤30,且 3≤n≤500
100%的测试点输入数据保证 1≤T≤50,且 3≤n≤2000

此处无声胜有声(待解决2333)

问题 E: 金子数

题目描述

某地区有 n 条(编号依次为 1 到 n)互不交叉的道路,每条道路上都有 m 个数字,其中 能被 8 整除的数称为金子数,这个数字表示其重量。
如下表是 3 条道路,每条道路中有 5 个数的一种可能情况。
就是这张图
小华想在 n 条道路中走一条金子重量之和最大的道路,请编程帮他找出这条道路吧.

输入

输入共 n+1 行。
第 1 行两个整数 n 和 m,表示总共有 n 条道路,每条道路上有 m 个数。 接下来 n 行,每行 m 个正整数。

输出

输出共 1 行。 一个整数,表示金子重量之和最大的道路编号。

样例输入
复制样例数据 3 5
13 24 17 8 23
1 2 3 4 5
16 2 16 4 8

样例输出
3

提示

输入的样例中,金子重量之和最大的道路编号为 3,具体情况见问题描述。

30%的测试点输入数据保证 1≤n≤10,1≤m≤100,路上的每个数都不超过 100。
100%的测试点输入数据保证 1≤n≤100,1≤m≤10000,路上的每个数都不超过 100000。 所有的测试点输入数据保证金子重量之和最大的道路只有一条,且肯定存在。

这算是一道水题,直接求和比大小输出结果即可

#include<bits/stdc++.h>
using namespace std;
struct node{
  int id;
  int sum;
}a[1000010];
bool cmp(node a,node b) {
  return a.sum>b.sum;
}
int main() {
  int n,m,x;
  cin>>n>>m;
  for(int i=0;i<n;i++) {
    a[i].id=i+1;
    for(int j=1;j<=m;j++) {
      cin>>x;
      if(x%8==0)
      a[i].sum+=x;
    }
  }
  sort(a,a+n,cmp);
  cout<<a[0].id;
}

问题 F: 扑克牌游戏

题目描述

扑克牌有 13 种代表不同点数的牌(不考虑花色),如下图所示,从左到右依次为“A”, “2”,“3”,“4”,…… ,“10”,“J”,“Q”,“K”。
在这里插入图片描述
为了你们的体验好一点我还是坚持把图都上传了= =!
小华正在玩一个扑克牌的游戏,在这个游戏中,每种点数的牌都有一个分数(不一定 跟点数相同)。现在小华手上已经有 n 张扑克牌,他还可以挑选 m 张扑克牌,使得 n+m 张 扑克牌的总分数最大。我们假定每种点数的扑克牌有无穷多张。
请编程计算小华在游戏中可以最多获得多少分?

输入

输入共 3 行。
第 1 行 13 个整数,依次表示每种点数的牌所代表的分数。
第 2 行两个整数 n 和 m,表示小华已经有 n 张扑克牌,还可以挑选 m 张扑克牌。
第 3 行输入表示小华手上已经有的 n 张扑克牌的情况,输入的两张扑克牌信息之间没有 空格分隔。

输出

输出共1行。 输出一个整数,表示小华在游戏中可以获得的最大分数。注意:小华选牌的方案可能不唯一,但只要总分数最大即可,不需要输出选牌的方案。

样例输入
复制样例数据 1 3 1 1 1 1 2 3 4 1 3 0 1
3 2
234

样例输出
13

提示

小华原来手上有 3 张牌,分别为“2”,“3”,“4”,对应的分数之和为 3+1+1=5,他可以 再挑选 2 张扑克牌,都是点数为“9”的扑克牌,这 2 张牌的分数之和为 4+4=8,所以小华的总得分为 13 分。

50%的测试点输入数据保证小华手上已经有的牌中不会出现“A”、“10”、“J”、“Q”、“K” 这 5 种点数的牌。
80%的测试点输入数据保证小华手上已经有的牌中不会出现“10”这种点数的牌。
100%的测试点输入数据保证 1≤n≤100,0≤m≤100,0≤每种点数的牌所代表的分数≤1000。

这题罚时两小时= = 就是因为没有理解测试点的意思,我以为没有A 10 J Q K 这五张牌 于是一直没有加上去,以后我就知道这个测试点只是oi用的,跟oj没有半毛钱关系,这种错误不会再犯了 代码:

#include<bits/stdc++.h>
using namespace std;
int a[100000];
int main() {
  for(int i=1;i<=13;i++)
  cin>>a[i];
  int n,m;
  cin>>n>>m;
  string b;
  cin>>b;
  int sum=0;
  for(int i=0;i<n;i++) {
    if(b[i]>='2'&&b[i]<='9')
    sum+=a[b[i]-'0'];
    if(b[i]=='A')
    sum+=a[1];
    if(b[i]=='J')
    sum+=a[11];
    if(b[i]=='Q')
    sum+=a[12];
    if(b[i]=='K')
    sum+=a[13];
    if(b[i]=='1'&&b[i+1]=='0') {
      sum+=a[10];
      n++;
    }
  }
  sort(a+1,a+14,greater<int>());
  sum+=a[1]*m;
  cout<<sum;
}
这里注意一下下标的问题 还有我排序是降序排的,也可以升序

问题 G: 垃圾装袋
题目描述

某城市环卫部门需要对分布在城市中不同地点的 n 堆(编号为 1 到 n)垃圾进行装袋处 理。现在有 m 个(编号为 1 到 m)垃圾袋可以使用。

一个容量为 v 的垃圾袋能装入不超过容量为 v 的垃圾,一堆垃圾要求只能用一个垃圾 袋来装,一个垃圾袋也只能用来装一堆垃圾(即一个垃圾袋不能在两个地方装垃圾)。一个 垃圾袋的价格是由垃圾袋的容量来决定,容量为 v 的垃圾袋价格为 v。

请编程帮环卫部门计算要将 n 堆垃圾全部装袋,用掉的垃圾袋最少值多少钱?

输入

输入共 3 行。
第 1 行两个正整数 n 和 m,表示需要处理 n 堆垃圾,现在有 m 个垃圾袋。 第 2 行 n 个整数,依次表示每堆垃圾的容量。
第 3 行 m 个整数,依次表示每个垃圾袋的容量。

输出

输出共 1 行。 输出一个整数,如果能将所有的垃圾装入已有的袋子,则输出用掉的垃圾袋最少值多少

钱?如果无法将所有的垃圾装入 m 个袋子,则输出“-1”。

样例输入
复制样例数据 3 4
3 6 4
4 5 7 3

样例输出
14

提示

有3堆垃圾,4个袋子,第1堆容量为3的垃圾用第4个容量为3的袋子装,第2堆容
量为6的垃圾用第3个容量为7的袋子装,第3堆容量为4的垃圾用第1个容量为4的袋子 装,所以用掉的垃圾袋最少值3+7+4=14。

30%的测试点输入数据保证1≤n,m≤1000
70%的测试点输入数据保证1≤n,m≤10000
100%的测试点输入数据保证1≤n,m≤50000,每个垃圾袋的容量和每处垃圾的容量 不超过10000。

本题和上次马同学晚上讲到的勇者斗恶龙是一个模子刻出来的,典型的一个贪心题目,但是当时被别的题目缠身不能自拔,再加上
被这个题吓破胆了,才没有做出来,后来一看这题跟那题一样 于是就a了 具体的思想是先排序,然后一个一个找,从最小的袋子
开始,如果找到就把袋子标记上,表示已经能够用过这个袋子了,然后用 sum加上最后输出就行了,注意控制最后输出的条件是
num==n且sum>0; 代码:
#include<bits/stdc++.h>
using namespace std;
int lj[100000];
int dz[100000];
int bk[100000];
int main() {
	int n,m;
	memset(bk,0,sizeof(bk));
	cin>>n>>m;
	for(int i=0;i<n;i++)
	cin>>lj[i];
	for(int i=0;i<m;i++)
	cin>>dz[i];
	int sum=0;
	int num=0;
	sort(lj,lj+n);
	sort(dz,dz+m);
	for(int i=0;i<m;i++)
	for(int j=0;j<n;j++) {
		if(!bk[j]&&dz[i]>=lj[j]) {
			num++;
			bk[j]=1;
			sum+=dz[i];
			break;
		}
	}
	if(num==n&&sum>0) 
	cout<<sum;
	else 
	cout<<"-1";
}

问题 H: 组装玩具
题目描述

小华打算用 n 种(编号为 1 到 n)材料组装玩具。其中第 i 种材料的数量为 Xi 个。组装一个玩具需要第 i 种材料 Yi 个。小华另外有 m 个万能材料,每个万能材料可以作为 n 种材料中的任意一个材料使用。

请编程计算小华最多可以组装多少个玩具?

输入

输入共3行。
第1行两个整数n和m,分别表示小华有n种材料和m个万能材料。第2行n个正整数,其中第i个整数Xi表示小华第i种材料有Xi个。
第3行n个正整数,其中第i个整数Yi表示小华组装一个玩具需要第i种材料Yi个。

输出

输出共 1 行。
一个整数,表示小华最多可以组装多少个玩具。

样例输入
复制样例数据 1 1
1
1

样例输出
2

提示

输入中小华只有1个编号为1的材料,另外还有1个万能材料。组装一个玩具需要编号为1的材料1个。所以可以用1个编号为1的材料和1个万能材料分别组装1个玩具,共可以组装2个玩具。
50%的测试点输入数据保证1≤n≤1000, 1≤m≤104,1≤Xi, Yi≤104。
100%的测试点输入数据保证1≤n≤100000, 1≤m≤109,1≤Xi, Yi≤109。

此处无声胜有声(待解决2333)

问题 I: 判奇偶

题目描述

小洪对偶数很感兴趣,现在有一个整数,他想对这个数进行如下操作:如果这个数是偶数的话就除以2,如果这个数是奇数的话就乘以2,那最后的结果是多少呢?

输入

只有1个正整数(小于1000000)。

输出

一个正整数,表示处理后结果。

样例输入
复制样例数据 90

样例输出
45

基础语法题(话说这才叫无敌大水题好不好!!)

#include<bits/stdc++.h>
using namespace std;
int main() {
  int n;
  cin>>n;
  if(n%2==0)
  cout<<n/2;
  if(n%2!=0)
  cout<<n*2;
}

问题 J: 零花钱

题目描述

小洪妈妈每个星期一早上就会给她s元的零花钱,每到星期五晚上她就要告诉妈妈还剩下多少钱,并且把剩余的钱上交。已知她星期一至星期五每天花费的金额,现在请你帮忙算出小洪星期五晚上还剩下多少钱。

输入

第一行:一个整数s,代表星期一早上母亲给的金额。(0<s<=100)
第二行:五个整数,分别代表小洪每天的消费金额。

输出

一行:一个整数,代表星期五晚上小洪还剩下多少钱。

样例输入
复制样例数据 50
5 5 11 10 5

样例输出
14

小学减法题…

#include<bits/stdc++.h>
using namespace std;
int main() {
  int n,x;
  cin>>n;
  for(int i=0;i<5;i++) {
    cin>>x;
    n-=x;
  }
  cout<<n;
}

问题 K: 统计数字

题目描述

小洪最近学了正整数和负整数,她现在面对一组整数,想算出这组整数有多少个正整数,多少个负整数,以及正整数的和是多少,负整数的和是多少。

输入

第一行:一个正整数n,代表有n个整数(0<n<=100)。
第二行:n个空格分开的整数(小于等于1000)。

输出

第一行:两个整数,代表正整数的个数和正整数的和(如果没有正数就输出0 0)。
第二行:两个整数,代表负整数的个数和负整数的和(如果没有负数就输出0 0)。

样例输入
复制样例数据 6
12 40 15 -20 48 -50

样例输出
4 115
2 -70

大水题不解释

#include<bits/stdc++.h>
using namespace std;
int main() {
  int n,sum1=0,sum2=0,x,a=0,b=0;
  cin>>n;
  for(int i=0;i<n;i++) {
    cin>>x;
    if(x>0) {
      a++;
      sum1+=x;
    }
    if(x<0) {
      b++;
      sum2+=x;
    }
  }
  cout<<a<<" "<<sum1<<"\n"<<b<<" "<<sum2;
}

问题 L: 译码程序
题目描述

小洪想请你编写一个译码程序,把一个英语句子译成数字代码。译码规则是以数字1代替字母a,数字2代替字母b,…,26代替字母z,如遇空格则打印一个‘#’,英文句子以’.’结束。

输入

一行以字符’.’结束的由小写字母、空格组成的字符串(长度小于255)。

输出

一行,译码以后的字符串。

样例输入
复制样例数据 i am chinese.

样例输出
9#113#389145195

这题需要注意一下用string的话必须用getline 不然遇到空格就GG if里面设置下遇到“.”的情况就okk了

代码:

#include<bits/stdc++.h>
using namespace std;
int main() {
  string a;
  getline(cin,a);
  for(int i=0;i<a.size();i++) {
    if(a[i]=='a')
    cout<<1;
    if(a[i]=='b')
    cout<<2;
    if(a[i]=='c')
    cout<<3;
    if(a[i]=='d')
    cout<<4;
    if(a[i]=='e')
    cout<<5;
    if(a[i]=='f')
    cout<<6;
    if(a[i]=='g')
    cout<<7;
    if(a[i]=='h')
    cout<<8;
    if(a[i]=='i')
    cout<<9;
    if(a[i]=='j')
    cout<<10;
    if(a[i]=='k')
    cout<<11;
    if(a[i]=='l')
    cout<<12;
    if(a[i]=='m')
    cout<<13;
    if(a[i]=='n')
    cout<<14;
    if(a[i]=='o')
    cout<<15;
    if(a[i]=='p')
    cout<<16;
    if(a[i]=='q')
    cout<<17;
    if(a[i]=='r')
    cout<<18;
    if(a[i]=='s')
    cout<<19;
    if(a[i]=='t')
    cout<<20;
    if(a[i]=='u')
    cout<<21;
    if(a[i]=='v')
    cout<<22;
    if(a[i]=='w')
    cout<<23;
    if(a[i]=='x')
    cout<<24;
    if(a[i]=='y')
    cout<<25;
    if(a[i]=='z')
    cout<<26;
    if(a[i]==' ')
    cout<<"#";
    if(a[i]=='.')
    break;
  }
}

本次成绩 铜牌(66名)下次继续努力!

猜你喜欢

转载自blog.csdn.net/weixin_43537190/article/details/84901479