题解目录(共4题)
2013南邮“华为杯”习题册
A.参赛选手身高问题
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
问题描述
2013“华为杯”南京邮电大学大学生团体歌唱大赛即将在南邮举行,本次大赛由南京邮电大学大学生就业与创业指导中心主办,南京邮电大学华为俱乐部(Huawei Club)和南京邮电大学学生职业发展协会(SCDA)联合承办,华为技术有限公司提供赞助。
为了展示南邮学子风采,大赛组委会规定:每个参赛团体由3名同一年级在校本科生或硕士研究生选手组成,3名选手按照身高等差排列,例如参赛团体中3个选手身高依次为160厘米、170厘米、180厘米,则该团体报名成功。
现在的问题是:给定报名成功团体中的最矮和中等身高选手的身高值,请你求解出最高身高选手的身高值。
问题输入
输入包括多个测试用例,首先给出测试用例数N,接着给出N个测试用例,每一个测试用例包括1行,依次给出最矮身高选手的身高值L、中等身高选手的身高值M,1≤N≤1000,150≤L≤M≤210,身高单位为厘米。
问题输出
输出包括多行,对于每个测试用例输出一行,给出最高身高选手的身高值。
样例输入
2
160 170
170 170
样例输出
180
170
思路分析
这还能说啥,签到题,拼手速即可。
参考代码(AC)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int l, m;
cin >> l >> m;
int d = m - l;
cout << m + d << endl;
}
return 0;
}
B.参赛选手信息更新问题
时间限制(普通/Java):2000MS/6000MS 运行内存限制:65536KByte
问题描述
根据题目A的问题描述,我们知道2013“华为杯”南京邮电大学大学生团体歌唱大赛要求每个参赛团体由3名同一年级在校学生选手组成,各位同学踊跃报名,赛事组委会收到大量参赛团体信息,包括每一个团体选手姓名、学号、年级、联系方式等。
因最近流感来袭,大赛组委会根据选手建议,决定将赛事推迟到秋季。该项决定带来的问题是:参赛团体的年级信息需要更新,其中已毕业离校参赛团队的信息需要删除。
我们将问题进行简化,大学一年级至四年级的信息依次用0、1、2、3表示,硕士研究生一年级至三年级的信息依次用4、5、6表示,给定参赛团体的年级信息,请你输出更新后的年级信息,如果选手已毕业,则无需输出。这里我们规定,参赛团体每位选手都正常升级或毕业,原来大学四年级或硕士研究生三年级的选手一律认为已毕业了。
问题输入
输入包括多个测试用例,首先给出测试用例数N,接着给出N个测试用例,每一个测试用例包括1行,首先给出参赛团体总数M,再依次给出M个参赛团体的年级信息,1≤N≤1000, 1≤M≤1000。
问题输出
输出包括多行,对于每个测试用例输出一行,依次输出更新后的年级信息,如果选手已毕业,则无需输出。
样例输入
2
5 1 2 4 5 6
4 0 0 6 6
样例输出
2 3 5 6
1 1
思路分析
这题也是个水题,就是有个坑……就是万一某一组的人全部毕业了,则不用输出任何东西,**但是需要输出换行!!换行!!换行!!!**其余的话,不毕业的存进一个队列里,然后按序从队列里面输出就可以了。
参考代码(AC)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
queue<int> qu;
for (int i = 0; i < n; i++) {
int m;
cin >> m;
int arr[m];
for (int j = 0; j < m; j++) {
cin >> arr[j];
if (arr[j] == 3 || arr[j] == 6)
;
else {
qu.push(arr[j] + 1);
}
}
int len = qu.size();
if (len == 0) //如果全部毕业,则输出换行,结束这组数据
cout << endl;
else {
for (int j = 0; j < len; j++) {
if (!qu.empty()) {
cout << qu.front();
qu.pop();
}
if (!qu.empty())
cout << ' ';
else
cout << endl;
}
}
}
return 0;
}
C.比赛成绩排序问题
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
问题描述
2013“华为杯”南京邮电大学大学生团体歌唱大赛比赛形式为:大赛分为多轮,每一轮随机选择参赛团体进行两两PK赛。当根据多轮多场的PK赛成绩能够确定排名次序时,大赛结束。
我们将问题进行简化,从1开始按递增顺序给每一个参赛团体分配一个整数编号,已知多场PK赛成绩,请你根据胜负关系确定两个给定参赛团体之间的成绩排名次序。举一个例子,参赛团体1在PK赛中胜参赛团体3,参赛团体2在PK赛中胜参赛团体1,则可知参赛团体2的成绩比参赛团体3的成绩排名高。
问题输入
输入包括多个行:
●第1行给出参赛团体总数M、已知PK赛成绩的场次C;
●接下来有C行,每一行先后给出两个参赛团体编号p和q,表示编号为p的参赛团体在
PK赛中胜编号为q的参赛团体;
●最后1行先后给出两个参赛团体编号x和y。
这里1≤M≤1000,1≤C≤10000,1≤p≤1000,1≤q≤1000,1≤x≤1000,1≤y≤1000,p≠q,x≠y。
问题输出
针对问题输入最后一行先后给出两个参赛团体编号x和y,输出1行,表示编号为x的参赛团体和编号为y的参赛团体之间的成绩先后次序,具体规定如下:
●编号为x的参赛团体的成绩排名比编号为y的参赛团体高,则输出x;
●编号为y的参赛团体的成绩排名比编号为x的参赛团体高,则输出y;
●不能确定编号为x的参赛团体和编号为y的参赛团体之间的成绩先后次序,则输出字符
串N/A。
样例输入1
3 2
1 3
2 1
2 3
样例输出1
2
样例输入2
3 2
1 3
2 1
3 2
样例输出2
2
样例输入3
3 1
1 3
2 1
样例输出3
N/A
思路分析
本来想写个并查集,后来觉得不对,和队友思索了一会儿后一致认为是拓扑排序,之前考虑到可不可以暴力,但是怕爆炸,估计会T掉,所以没敢写。其实最后发现就是个DFS……这里用邻接表实现。
参考代码(AC)
#include <bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for(int i = (a); i < (b); i++)
#define _fore(i, a, b) for(int i = (a); i <= (b); i++)
#define MEM0(a) memset(a, 0, sizeof(a))
#define MEM1(a) memset(a, -1, sizeof(a))
#define gcd(a, b) __gcd(a, b)
#define INF 0x3f3f3f3f
struct Edge {
int fro;
int to;
int nxt;
} E[10010];
int head[1005];
bool vis[1005];
int cnt = 0;
void addE(int fro, int to) {
E[cnt].fro = fro;
E[cnt].to = to;
E[cnt].nxt = head[fro];
head[fro] = cnt;
cnt++;
}
int u,v;
bool dfs(int s) {
for(int i = head[s]; i != -1; i = E[i].nxt) {
int to = E[i].to;
if(vis[to])
continue;
vis[to] = true;
if(to == v)
return true;
if(dfs(to))
return true;
}
return false;
}
int main() {
MEM1(head);
MEM0(vis);
int M, C;
cin >> M >> C;
for(int i = 0; i < C; i++) {
int a, b;
cin >> a >> b;
addE(a, b);
}
int a, b;
cin >> a >> b;
u = a, v = b;
if(dfs(a)) {
cout << a << endl;
return 0;
}
u = b, v = a;
if(dfs(b)) {
cout << b << endl;
return 0;
}
cout << "N/A" << endl;
return 0;
}
D.比赛现场气氛营造问题
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
问题描述
在2013“华为杯”南京邮电大学大学生团体歌唱大赛组织工作中,为了营造比赛现场活跃气氛,大赛组委会决定为每位观众发放相同数目的OLED多彩荧光棒。现在我被委派批量采购荧光棒,大赛组委会特别要求:留1个荧光棒备用,其他所有的荧光棒都要平均发放给观众。已知目前市场上OLED多彩荧光棒只能按整包出售,每整包中的荧光棒数目相同。
借此次“华为杯”南邮大学生程序设计竞赛的机会,请你帮我解决以下问题:已知观众数目、每整包中的OLED多彩荧光棒数目,我去采购,能否可能满足大赛组委会的特别要求。
问题输入
输入包括多个测试用例,首先给出测试用例数N,接着给出N个测试用例,每一个测试用例包括1行,给出观众数目M、每整包中的OLED多彩荧光棒数目T,1≤N<1000,1≤M≤109, 1≤T≤109,购买OLED多彩荧光棒总数不超过109。
问题输出
针对每一个测试用例,如果有任何一种购买方案(特定整包数)使得满足大赛组委会的特别要求,则在一行中输出字符串Yes;如果无论怎么采购都不能满足大赛组委会的特别要求,则在一行中输出字符串No。
样例输入
5
3 3
3 4
5 6
7 4
51 45
样例输出
No
Yes
Yes
Yes
No
思路分析
这是一道初等数论问题。设每个观众被分到x个荧光棒,“我”一共买了y包荧光棒。那么有方程:
M · x + 1 = T · y
这就很神奇了,因为这是一个关于x,y的二元一次不定方程有整数解的初等数论问题。
有定理:
在整系数方程ax+by=c中,若a,b的最大公约数能被c整除,则方程有整数解。即 如果gcd(a,b)|c 则方程ax+by=c有整数解。
那这道题岂不是可以被秒……
参考代码(AC)
#include <bits/stdc++.h>
#define gcd(a,b) __gcd(a,b)
#define _for(i,a,b) for(int i = (a); i < (b); i++)
#define _fore(i,a,b) for(int i = (a); i <= (b); i++)
using namespace std;
int main() {
int n;
cin >> n;
_for (i, 0, n) {
int m, t;
cin >> m >> t;
if (gcd(m,t) == 1)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}