猜数字游戏的提示,Master-Minds Hints,UVa 340 《算法竞赛入门经典》 (Java语言)

书上的中文题、和原版的英文题目都看了很多遍,没有看懂,后来看网上的题解看懂的,这里想把题目再次解释一下。

参考网页:

https://blog.csdn.net/oceaniwater/article/details/7947558

http://blog.163.com/kakarrot@yeah/blog/static/12011592520106241155854/

英文原版题目如下,其中给出关键题点的中文解释:

MasterMind is a game for two players. One of them, Designer, selects a secret code. (设计者设计一行密码)The other, Breaker,
tries to break it. A code is no more than a row of colored dots. At the beginning of a game, the players
agree upon the length N that a code must have and upon the colors that may occur in a code.
In order to break the code, Breaker makes a number of guesses(破解者给出多行猜测), each guess itself being a code. After
each guess Designer gives a hint, stating to what extent the guess matches his secret code(给出破解者所猜的序列与密码的匹配度暗示).
In this problem you will be given a secret code s1 . . . sn and a guess g1 . . . gn,(密码序列和猜测序列长度均为n) and are to determine
the hint. A hint consists of a pair of numbers determined as follows.
A match is a pair (i, j), 1 ≤ i ≤ n and 1 ≤ j ≤ n,(i是s序列中的下标,j是g序列中的下标) such that si = gj(i,j的匹配是满足s序列中的第i个数和g序列中的第j个数相等) . Match (i, j) is called strong
when i = j, (当下标i,j相等时,为强匹配,即数值和位置都相同)and is called weak otherwise(其他情况叫弱匹配,即值相等,位置不同). Two matches (i, j) and (p, q) are called independent when
i = p if and only if j = q. A set of matches is called independent when all of its members are pairwise
independent.
Designer chooses an independent set M of matches for which the total number of matches and the
number of strong matches are both maximal. The hint then consists of the number of strong followed
by the number of weak matches in M(在M中第一个数为强匹配的个数,第二个数为弱匹配的个数). Note that these numbers are uniquely determined by the secret
code and the guess. If the hint turns out to be (n, 0), then the guess is identical to the secret code(当hint为(n,0)时,表示猜测和密码相同).
Input
The input will consist of data for a number of games. The input for each game begins with an integer
specifying N (the length of the code)(第一行是密码序列的长度N). Following these will be the secret code, represented as N integers,(第二行是长度为N的密码序列)
which we will limit to the range 1 to 9(范围在1-9之间). There will then follow an arbitrary number of guesses(接下来是相同长度的猜测序列), each
also represented as N integers, each in the range 1 to 9. Following the last guess in each game will be
N zeroes(在猜测结束后输入N个0); these zeroes are not to be considered as a guess.(0序列不包括在猜测序列中)
Following the data for the first game will appear data for the second game (if any) beginning with a
new value for N. The last game in the input will be followed by a single ‘0’(N=0时游戏结束) (when a value for N would
normally be specified). The maximum value for N will be 1000.
Output
The output for each game should list the hints that would be generated for each guess(输出的每个hint由输入的猜测序列生成), in order, one hint
per line(每行输出一个hint). Each hint should be represented as a pair of integers enclosed in parentheses and separated by
a comma. The entire list of hints for each game should be prefixed by a heading indicating the game
number; games are numbered sequentially starting with 1(游戏的标号从1开始). Look at the samples below for the exact
format.
Sample Input
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
Sample Output
Game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
Game 2:
(2,4)
(3,2)
(5,0)
(7,0)

《算法竞赛入门经典》中文题目如下:

    实现一个经典“猜数字”游戏。给定答案序列和用户猜的序列,统计有多少数字位置正确(A),有多少数字在两个序列中都出现过但位置不对(B)。

    输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。

解释:

如果给出的数字和猜测的数字意义,并且在同一列上(即i=j)那么就是括号(A,B)左边的数字A加一,即A=A+1;如果位置不一样,数字一样,则B=B+1。A(strong),B(weak)。

解题代码如下:

import java.util.Scanner;

public class Main {
	public static int[] getStrongAndWeak(int[] s,int[] g)
	{
		int[] strong=new int[10];//1-9数字所提供的strong值,0位置留空
		int[] weak=new int[10];//1-9数字所提供的weak值,0位置留空
		int[] w1=new int[10];int[] w2=new int[10];
		int[] result=new int[2];//第一个数为strong,第二个数为weak
		for(int i=0,j=0;i<s.length;i++,j++)
		{
			w1[s[i]]++;//该位置上的数值出现的次数先存入w1数组
			w2[g[j]]++;//该位置上的数值出现的次数先存入w2数组
			if(s[i]==g[j]){
			//该位置上的数值对应的strong值增加
				strong[s[i]]++;
				result[0]++;
			}
			
		}

		for(int n=1;n<weak.length;n++)//获得weak数组
		{//统计在两个序列中,对于每个数字(1-9)出现的次数w1,w2,则min(w1,w2)就是该数字对weak的贡献,最后减去满足strong的个数
			weak[n]=(w1[n]<w2[n]?w1[n]:w2[n])-strong[n];
			result[1]+=weak[n];
		}
		//System.out.println("strong:");
		//printArr(strong);
		//System.out.println("weak:");
		//printArr(weak);
		return result;
	}
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int count=0;
		while(true){
			int N=in.nextInt();
			if(N==0){
				break;//N=0时猜数游戏结束
			}
			count++;//开始一局新游戏
			int []s=new int[N];//secret序列
			for(int i=0;i<N;i++)//初始化secret序列
			{
				s[i]=in.nextInt();
			}
			
			System.out.println("Game "+count+":");
			while(true)//开始猜测
			{
				int []g=new int[N];//guess序列
				int first=in.nextInt();//正常的guess序列不会有0,所以只判断第一个数是否为0即可
				if(first==0){//如果输入0序列,猜测结束
					for(int i=1;i<N;i++)
					{//在序列连读N个0退出猜测进入下一轮游戏时,要先从缓冲区把这N个0读出,防止对新一轮游戏的N的读入产生干扰
						in.nextInt();
					}
					break;
				}
				int j=0;
				g[j]=first;j++;
				for(;j<N;j++)//初始化guess序列
				{
					g[j]=in.nextInt();
				}

				int[] result=getStrongAndWeak(s, g);
				System.out.println("    ("+result[0]+","+result[1]+")");
			}
		}
		in.close();
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值