刚开始题目没理解,卡了好久,后来仔细研究了下,发现题目是这个意思:
如果两个序列的对应位置数字相等,那么被称为强匹配(a1);
如果该数字在两个序列中都出现过,且位置不同,那么被称为弱匹配(a2);
注意,只要该位置数字被用于强匹配或弱匹配的计算,那么该数字将不再被使用;
举两个例子:
答案:1 2 2 2 4 5 6 6 6 9
猜数:1 2 3 4 5 6 7 8 9 1
第一次循环用来寻找强匹配的数量,即a1的值。
对两个数组进行比较后发现,前两位一一对应,因此由于这两位数字被用于参加强匹配的统计,所以在之后的统计中这四个数字不再被使用,因为我们让这四位数字变为-1。
即第一次循环后的情况
变更前 1 2 2 2 4 5 6 6 6 9
变更后 -1 -1 2 2 4 5 6 6 6 9
变更前 1 2 3 4 5 6 7 8 9 1
变更后 -1 -1 3 4 5 6 7 8 9 1
现在来统计若匹配的情况
我的思路是用猜数序列的非负数来匹配答案序列,若匹配到,则a2++,答案序列的该数字变为-1(个人感觉这种方法更好理解,其实是因为菜)
-1 -1 2 2 4 5 6 6 6 9
-1 -1 3 4 5 6 7 8 9 1
第一次用3匹配答案序列,遍历之后,没有匹配
//其实前两次应该用开始的两个数匹配,只不过已经使用过了,所以continue就可以了
第二次用4匹配答案序列,答案序列有与之匹配的4,因此令答案序列的4变为-1
匹配:
-1 -1 2 2 -1 5 6 6 6 9
-1 -1 3 4 5 6 7 8 9 1
第三次用5匹配
匹配:
-1 -1 2 2 -1 -1 6 6 6 9
-1 -1 3 4 5 6 7 8 9 1
第四次用6匹配
匹配:
-1 -1 2 2 -1 -1 -1 6 6 9
-1 -1 3 4 5 6 7 8 9 1
第五次用7匹配
无匹配:
continue;
第六次用8匹配无匹配;
continue;
以此类推,直到最后一次
用1匹配,因为答案序列的1已经因为有与之对应的强匹配而使用过,所以1无匹配,至此,序列遍历完成;
因为序列中不可能有0,所以只要猜数序列第一位检测到0就可以退出
下面附上AC代码
#include <cstdio>
int main()
{
int n, i, j, answer[1000], guess[1000], k = 0;
while (scanf("%d", &n) == 1 && n)
{
for (i = 0; i < n; i++)
scanf("%d", &answer[i]);
printf("Game %d:\n", ++k);
while (1)
{
int a1 = 0, a2 = 0, temp[1000] = { 0 };
for (i = 0; i < n; i++)
temp[i] = answer[i];
for (i = 0; i < n; i++)
scanf("%d", &guess[i]);
if (guess[0] == 0)
break;
for (i = 0; i < n; i++)
if (temp[i] == guess[i])
{
a1++;
temp[i] = -1;
guess[i] = -1;
}
for (i = 0; i < n; i++)
{
if (guess[i] == -1)
continue;
for (j = 0; j < n; j++)
{
if (temp[j] == -1)
continue;
if (guess[i] == temp[j] && temp[j] >= 0)
{
a2++;
temp[j] = -1;
break;
}
}
}
printf(" (%d,%d)\n", a1, a2);
}
}
return 0;
}