PAT每日三题

1089 狼人杀-简单版

分数 20

作者 CHEN, Yue

单位 浙江大学

以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?

本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?

输入格式:

输入在第一行中给出一个正整数 N(5≤N≤100)。随后 N 行,第 i 行给出第 i 号玩家说的话(1≤i≤N),即一个玩家编号,用正号表示好人,负号表示狼人。

输出格式:

如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a[1],...,a[M] 和 B=b[1],...,b[M],若存在 0≤k<M 使得 a[i]=b[i] (i≤k),且 a[k+1]<b[k+1],则称序列 A 小于序列 B。若无解则输出 No Solution

输入样例 1:

5
-2
+3
-4
+5
+4

输出样例 1:

1 4

输入样例 2:

6
+6
+3
+1
-5
-2
+4

输出样例 2(解不唯一):

1 5

输入样例 3:

5
-2
-3
-4
-5
-1

输出样例 3:

No Solution
/*
* 题目是说问谁是狼,并且给出了结果
* 有两人说谎,不是所有狼人都说谎了
* 如果单纯用正向思考,那么很难有思路
* 这时候反向思考,直接枚举狼,然后判断是否满足条件
方法:枚举
枚举所有的狼(保证序列A小于序列B)
然后将枚举的说话结果与正确的答案做对比
确实是有一个狼说真话,有一个狼说假话
那么该匹配正确,否则不对
*/

#include<iostream>
#include<string>
#include<cmath>
#include<vector>
using namespace std;


int main() {

	int n;
	cin >> n;
	vector<int> arr(n + 1,0);
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}
	bool find = false;
	for (int i = 1; i <= n; i++) {
		for (int j = i+1; j <= n; j++) {
			//狼人(i,j)
			//通过根据大家说的话,判定解
			//两个说谎的人,一个狼,一个好人
			vector<int> lies;
			for (int k = 1; k <= n; k++) {
				//k说别人是好人,判断其说话正确与否
				if (arr[k] > 0) {
					//判定说话的人
					int p = abs(arr[k]);
					//如何p是狼那么假话
					if (p == i || p == j) {
						lies.push_back(k);
					}
				}
				//说被人是狼,如果是好人那么撒谎
				else {
					int p = abs(arr[k]);
					if (p != i && p != j) {
						lies.push_back(k);
					}
				}
			}
			//如果说谎的人有两个并且一个为狼一个为好人
			if (lies.size() == 2) {
				if ((lies[0] == i && lies[1] != j) || (lies[0] == j && lies[1] != i) ||
					(lies[0] != j && lies[1] == i) || (lies[0] != i && lies[1] == j)) {
					cout << i << " " << j << endl;
					find = true;
					break;
				}
			}

		}
		if (find) {
			break;
		}
	}
	if (find == false) {
		cout << "No Solution" << endl;
	}

	return 0;
}

1066 图像过滤

分数 15

作者 CHEN, Yue

单位 浙江大学

图像过滤是把图像中不重要的像素都染成背景色,使得重要部分被凸显出来。现给定一幅黑白图像,要求你将灰度值位于某指定区间内的所有像素颜色都用一种指定的颜色替换。

输入格式:

输入在第一行给出一幅图像的分辨率,即两个正整数 M 和 N(0<M,N≤500),另外是待过滤的灰度值区间端点 A 和 B(0≤A<B≤255)、以及指定的替换灰度值。随后 M 行,每行给出 N 个像素点的灰度值,其间以空格分隔。所有灰度值都在 [0, 255] 区间内。

输出格式:

输出按要求过滤后的图像。即输出 M 行,每行 N 个像素灰度值,每个灰度值占 3 位(例如黑色要显示为 000),其间以一个空格分隔。行首尾不得有多余空格。

输入样例:

3 5 100 150 0
3 189 254 101 119
150 233 151 99 100
88 123 149 0 255

输出样例:

003 189 254 000 000
000 233 151 099 000
088 000 000 000 255
#include<iostream>
#include<vector>
#include<string>
using namespace std;


int main() {

	int a, b, c, d, t;
	cin >> a >> b >> c >> d >> t;
	for (int i = 0; i < a; i++) {
		for (int j = 0; j < b; j++) {
			int p;
			cin >> p;
			if (p >= c && p <= d) {
				string q = to_string(t);
				while (q.size() < 3) {
					q = '0' + q;
				}
				cout << q;
			}
			else {
				string q = to_string(p);
				while (q.size() < 3) {
					q = '0' + q;
				}
				cout << q;
			}
			if (j != b - 1) {
				cout << " ";
			}
		}
		cout << endl;
	}



	return 0;
}

1074 宇宙无敌加法器

分数 20

作者 CHEN, Yue

单位 浙江大学

地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”。每个 PAT 星人都必须熟记各位数字的进制表,例如“……0527”就表示最低位是 7 进制数、第 2 位是 2 进制数、第 3 位是 5 进制数、第 4 位是 10 进制数,等等。每一位的进制 d 或者是 0(表示十进制)、或者是 [2,9] 区间内的整数。理论上这个进制表应该包含无穷多位数字,但从实际应用出发,PAT 星人通常只需要记住前 20 位就够用了,以后各位默认为 10 进制。

在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表“0527”,该如何计算“6203 + 415”呢?我们得首先计算最低位:3 + 5 = 8;因为最低位是 7 进制的,所以我们得到 1 和 1 个进位。第 2 位是:0 + 1 + 1(进位)= 2;因为此位是 2 进制的,所以我们得到 0 和 1 个进位。第 3 位是:2 + 4 + 1(进位)= 7;因为此位是 5 进制的,所以我们得到 2 和 1 个进位。第 4 位是:6 + 1(进位)= 7;因为此位是 10 进制的,所以我们就得到 7。最后我们得到:6203 + 415 = 7201。

输入格式:

输入首先在第一行给出一个 N 位的进制表(0 < N ≤ 20),以回车结束。 随后两行,每行给出一个不超过 N 位的非负的 PAT 数。

输出格式:

在一行中输出两个 PAT 数之和。

输入样例:

30527
06203
415

输出样例:

7201
#include<iostream>
#include<vector>
#include<string>
using namespace std;


int main() {

	string d;
	cin >> d;
	string a, b;
	cin >> a >> b;
	int i = d.size() - 1;
	int j = a.size() - 1;
	int k = b.size() - 1;
	int carry = 0;
	string r;
	//注意超过给出进制后按10进制处理
	while (j >= 0 || k >= 0 || carry) {
		int t = 0;
		if (j >= 0) {
			t += a[j] - '0';
		}
		if (k >= 0) {
			t += b[k] - '0';
		}
		
		t += carry;
		//0表示十进制
		if (d[i] == '0'||i<0) {
			carry = t / 10;
			r =  to_string(t % 10)+r;
		}
		else {
			carry = t / (d[i] - '0');
			r = to_string(t % (d[i] - '0'))+r;
		}
		
		i--;
		j--;
		k--;
	}
	i = 0;
	while (r[i] == '0') {
		i++;
	}
	r = r.substr(i);
	//注意为全零的情况
	if (r == "") {
		r = "0";
	}
	cout << r << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值