2013年第三届“华为杯”南邮大学生程序设计竞赛选拔赛题解报告

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值