2020复旦大学计算机考研机试题详解

写在前面

复旦巨喜欢考动规,建议好好准备


A、斗牛

给定五个 0~9 范围内的整数 a1, a2, a3, a4, a5。如果能从五个整数中选出三个并且这三个整数的和为10 的倍数(包括 0),那么这五个整数的权值即为剩下两个没被选出来的整数的和对 10 取余的结果,显然如果有多个三元组满⾜和是 10 的倍数,剩下两个数之和对 10 取余的结果都是相同的;如果
选不出这样三个整数,则这五个整数的权值为 -1。
现在给定 T 组数据,每组数据包含五个 0~9 范围内的整数,分别求这 T 组数据中五个整数的权值。

【输⼊格式】 第⼀⾏⼀个整数 T (1<=T<=1000),表⽰数据组数。 接下来 T ⾏,每⾏ 5 个 0~9 的整数,表⽰⼀组数据。

【输出格式】输出 T ⾏,每⾏⼀个整数,表⽰每组数据中五个整数的权值。

【样例输⼊】
4
1 0 0 1 0
1 0 0 8 6
3 4 5 6 7
4 5 6 7 8

【样例输出】
2
-1
-1
0

【解释】
在第⼀组(1 0 0 1 0)中,三元组 0 0 0 的和为 0,是 10 的倍数,剩余的 1 1 之和为 2,对 10 取余为2。
在第⼆组中,不存在任何⼀个三元祖只和为 10 的倍数。
在第四组中,三元组 5 7 8 的和为 20,是 10 的倍数,剩余的 4 6 只和为 10,对 10取余为 0。
在第五组中,三元组 0 3 7 和三元组 0 4 6 的和都是 10,是 10 的倍数,但是根据简单的数论可知,如果存在多个三元组满⾜情况,那么剩余数字的结果之和对 10 取余是相等的,在本例中和为 10,对 10取余为 0。

答案解析

基本思路:

其实就是判断是否有三数之和为10的倍数,而且确定总共只有五个数,那么可以用fou循环来解决,但是为了代码美观而且看起来牛掰点,还是使用了回溯法,二者的时间复杂度和空间复杂度是相同的。最后如果三数之和为10的倍数,那么只要五数之和减去三数之和就可以了。
时间复杂度:O(n)
空间复杂度:O(1)

回溯法:使用visited数组来记录每个元素的是否被访问过,每次确定一个元素,然后递归确定其他元素

代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//回溯法得到其中三数之和,若没有10的倍数,返回-1
int judge(int sum,vector<int>& visited,vector<int>D,int num) {
   
	if (num > 3)	return -1;
	if (num == 3 && sum % 10 == 0)	return sum;
	for (int i = 0; i < D.size(); i++) {
   
		if (visited[i] == 0) {
   
			visited[i] = 1;
			int f = judge(sum + D[i], visited, D, num + 1);
			if (f != -1)	return f;
			visited[i] = 0;
		}
	}
	return -1;
}

int main()
{
   
	int T;
	cin >> T;
	int N = 5;
	vector<vector<int>>data(T, vector<int>(N));
	for (int i = 0; i < T; i++) {
   
		for (int j = 0; j < N; j++) {
   
			cin >> data[i][j];
		}
	}
	vector<int>result;
	vector<int> visited(N, 0);	//记录已被访问过的数
	for (int i = 0; i < T; i++) {
   
		int sum = 0, num = 0;
		fill(visited.begin(), visited.end(), 0);
		int flag = judge(sum, visited, data[i], num);
		if (flag != -1) {
   	//存在三数之和为10的倍数
			int S = 0;
			for (int j = 0; j < N; j++)	S += data[i][j];
			result.
  • 23
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值