题目:
代码:
#include <stdio.h>
int* masterMind(char* solution, char* guess, int* returnSize) {
*returnSize = 2;
static int answer[2] = { 0 };//static关键字能使masterMind函数结束时,answer数组不会销毁
memset(answer, 0, sizeof(answer));//用memset函数将数组全部初始化为0
int s_answer[26] = { 0 };//26个字符位 solution 四种颜色数量统计
int g_answer[26] = { 0 };//26个字符位 guess 四种颜色数量统计
for (int i = 0; i < 4; i++) {
if (solution[i] == guess[i]) {
answer[0] += 1;//位置和颜色完全一致则猜中数量+1
}
else {
//统计同一位置不同颜色的两组颜色数量,伪猜中不需要对应位置相同,只需要有对应数量的颜色就行
s_answer[solution[i] - 'A'] += 1; //统计solution对应颜色字符出现次数
g_answer[guess[i] - 'A'] += 1;//统计guess对应颜色字符出现次数
}
}
//在两个颜色数量统计数组中查看颜色数量,取相同位置较小的一方就是为猜中数量
for (int i = 0; i < 26; i++) {
answer[1] += s_answer[i] > g_answer[i] ? g_answer[i] : s_answer[i];
}
return answer;
}
int main()
{
char solution[] = "BRBB";
char guess[] = "RBGY";
int returnSize = 0;
int* answer = masterMind(solution, guess, &returnSize);
for (int i = 0; i < returnSize; i++) {
printf("%d ", answer[i]);
}
return 0;
}
讲解:
“猜中”和“伪猜中”分别计数。
使用 if else 语句即可满足题目中 “猜中”不能算入“伪猜中” 这一条件。
for (int i = 0; i < 4; i++) { if (solution[i] == guess[i]) { answer[0] += 1;//位置和颜色完全一致则猜中数量+1 } else { //统计同一位置不同颜色的两组颜色数量,伪猜中不需要对应位置相同,只需要有对应数量的颜色就行 s_answer[solution[i] - 'A'] += 1; //统计solution对应颜色字符出现次数 g_answer[guess[i] - 'A'] += 1;//统计guess对应颜色字符出现次数 } }
二者的计数条件有区别,“猜中”是同一位置相等才加1,“伪猜中”是不同的位置但是猜到了就加1。
上述代码中同时遍历solution和guess数组,solution[i] == guess[i] 表示同一位置相等时,则只执行answer[0] += 1; 语句,不相等则只执行 s_answer[solution[i] - 'A'] += 1; g_answer[guess[i] - 'A'] += 1; 这样就将“猜中”和“伪猜中”的计数方式就区分开了。
“伪猜中”计数稍微复杂一点,相同的字母只能计数一次。
例如:
solution ="BRBB"
guess ="RBGY"
这时的“伪猜中”数只能是2,因为字母B只能计数一次。
//在两个颜色数量统计数组中查看颜色数量,取相同位置较小的一方就是为猜中数量 for (int i = 0; i < 26; i++) { answer[1] += s_answer[i] > g_answer[i] ? g_answer[i] : s_answer[i]; }
上述代码就可以完成对于重复的字母只计数一次的功能。无论是s_answer[i]大还是g_answer[i]大都取最小的一方。
当solution ="BRBB" ,guess ="RBGY"时,对于字母B,在 s_answer[26]中下标为1的数为3,在g_answer[26]中下标为1的数为1,则取较小的一方 g_answer[1]。
完