UVa340 - Master-Mind Hints 题解
题目
题目地址
题目大意
实现一个经典“猜数字”游戏。给定答案序列和用户猜的序列,统计有多少数字正确(A),有多少数字在两个序列都出现过但位置不对(B)。
输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。
样例输入
4
1 3 5 5
1 1 2 3
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
10
1 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0
样例输出
Game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
Game 2:
(2,4)
(3,2)
(5,0)
(7,0)
题解
题目分析
观察第一组输入,答案序列与第一次猜测序列为
1 3 5 5
1 1 2 3
只有第一位是相同的,所以A=1。
猜测序列里的第2位“1”为位置不对,第4位“3”同样是位置不对,所以B=2……诶不对,样例输出里的B为1。怎么回事?
是因为猜测序列第1位的“1”与答案序列第1位的“1”已经“配对”了,所以再计算B时候不能考虑已经配对的数字。所以A=1,B=1。
现在来换种思路考虑计算B。
两个序列中相同的“1”有1个(答案序列有1个,猜测序列有2个,取最小的那个),“2”有0个,“3”有1个,“5”有0个。
之前算出了A=1。现在可以算B=1+0+1+0-A。
考虑下为什么B要这样算。
Then show the code.
#include <stdio.h>
int main(){
//注意题目中的数据范围
int n, a[1005], b[1005], A, B, kase = 0;
int c1, c2;
while(scanf("%d", &n) == 1 && n){
for(int i=0; i<n; i++){
scanf("%d", &a[i]);
}
printf("Game %d:\n", ++kase);
while(1){
A = B = 0;
for(int i=0; i<n; i++){
scanf("%d", &b[i]);
}
//猜测序列全为0时只需要检查第一个是否为0
if(b[0] == 0)
break;
for(int i=0; i<n; i++){
if(a[i] == b[i])
A++;
}
//这里就是求B的第二种思路
for(int d=1; d<=9; d++){
c1 = c2 = 0;
for(int i=0; i<n; i++){
if(a[i] == d) c1++;
if(b[i] == d) c2++;
}
if(c1 > c2) B += c2;
else B += c1;
}
printf(" (%d,%d)\n", A, B-A);
}
}
return 0;
}
不忘初心方得始终