Uva-340. Master-Mind Hints

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/81990060

Uva-340. Master-Mind Hints题解

欢迎访问我的Uva题解目录哦https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

Uva-340. Master-Mind Hints题目描述

题意解析

题目给出了一个答案序列和一个猜的序列,要求统计出有两个序列中数字相同且位置相同的数字个数strong以及数字相同但位置不同的数字个数weak。

注意点

在统计数字相同但位置不同的数字个数weak时注意不能和数字相同且位置相同的数字进行比较。例如给定的答案序列为1 3 5 5,给定的猜的序列为1 1 2 3,假设序列数字位置由0开始,猜的序列1号位置上的数字1和答案序列0号位置上的数字1相同,但是猜的序列1号位置上的数字1不能被统计进入weak中,因为答案序列0号位置上的数字1和猜的序列0号位置上的数字1数字相同且位置相同,该数字可以被统计进入strong中,那么猜的序列1号位置上的数字1就不能再和答案序列0号位置上的数字1进行比较。而猜的序列3号位置上的数字3和答案序列1号位置上的数字3数字相同,但答案序列1号位置上的数字3并不能统计入strong中,所以该数字可以统计入weak中。通过上述讨论,可以得知需要先统计strong,再统计weak。

算法设计

由于给定的序列中数字范围为1~9,可以定义两个长度为10的一维数组codeFre和guessFre,数组元素下标代表序列中0~9这十个数字,元素内容表示该数字在序列中出现的次数,codeFre和guessFre分别对答案序列和猜的序列中的数字出现频率进行统计。先统计stron,遍历答案序列和猜的序列,如果对应位置上对应数字相同,假设该数字为n,那么strong递增1,以n为下标,将codeFre和guessFre对应元素分别递减1。再统计weak,遍历codeFre和guessFre两个数组,遍历过程中令weak+=min(guessFre[i],codeFreCopy[i])。最后输出strong和weak即可。

C++代码

#include<bits/stdc++.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)//for循环的一种用宏表示的简写方式
void readData(int*sequence,int*frequency,int N){//读入数据并统计序列中每个数字出现的频率
    fill(frequency,frequency+10,0);
    _for(i,0,N){
        scanf("%d",&sequence[i]);
        ++frequency[sequence[i]];
    }
}
int main(){
    int N,num=0,code[1005],guess[1005],codeFre[10],guessFre[10],codeFreCopy[10];
    scanf("%d",&N);
    while(N!=0){//N不为0继续游戏
        printf("Game %d:\n",++num);
        readData(code,codeFre,N);//读取答案序列
        readData(guess,guessFre,N);//读取猜的序列
        while(guessFre[0]<N){//猜的序列如果数字全为0的话,那么猜的序列0出现的频率就是N,可以用这一点作为一次游戏是否结束的标志
            memcpy(codeFreCopy,codeFre,sizeof(codeFre));//将codeFre数组元素拷贝到codeFreCopy中
            int strong=0,weak=0;
            _for(i,0,N)//统计两个序列中数字相同且位置相同的数字个数strong
                if(code[i]==guess[i]){
                    ++strong;
                    --codeFreCopy[code[i]];
                    --guessFre[guess[i]];
                }
            _for(i,0,10) weak+=min(guessFre[i],codeFreCopy[i]);//统计数字相同但位置不同的数字个数weak
            printf("    (%d,%d)\n",strong,weak);//输出,注意每行前要输出4个空格
            readData(guess,guessFre,N);//再次读入猜的序列
        }
        scanf("%d",&N);//读取N
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/81990060