题目描述
你童年时期就有一个梦想,想要加入 ACM(Association of Calculation and Magic),今天,这个机会终于 来了。
但是 ACM 只想要哪些天赋异禀的人, 比如像 tourist,他们给了你一道题来检测你是否足够机智。
猜一个长度为 m 数字串,总共有 n 个提示串,解释如下:
8640 0A2B
A 前面的数字说明与答案相比,有多少个位置上的数字是相同的。 B 前面的数字说明与答案相比,有多 少个数字是相同的,但是位置不一样。
0 A 就表示给出的串没有任何位置和答案是相同的。 2 B 就表示给出的串中有两个数字和答案相同,但 是位置不一样。
所以,对于上面那个提示串 6457 是一个合理的答案,但是 1234 并不是。
现在给你 N(N<=100) 个提示串(如上所示),你需要去找到一个数字串来符合每一个提示串的要求。
提示串中的每个数字都是不同的,即一个串中不会存在相同的数字。
你能解决这个问题并加入 ACM 吗?
输入
第一行两个数字,n(n<=100) 和 m(m<=9), 提示串的数量以及目标字符串的长度。
然后是 n 行,每行的格式如下:
s x y
s 是提示串,x 是 A 前的数字,y 是 B 前的数字,等同于:
s xAyB
输出
一行,目标串。
数据保证答案唯一。
样例输入 Copy
6 4
5164 3 0
5174 3 0
5194 3 0
5124 3 0
5134 3 0
5104 3 0
样例输出 Copy
5184
来源/分类
位数最多为9位,所以可以全排列下,再跟给的提示串都进行比较下,题目中说了答案唯一。
所以当前数字满足条件输出即可;接收提示串,不要用整串字符接受(一直WA);
#include<iostream>
#include<string>
#include<map>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int num[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int vis[11];
struct node{
char s[12];
int a, b;
}a[110];
int main(){
int n, m;
cin >> m >> n;
getchar();
for (int i = 1; i <= m; i++)
scanf("%s%d%d", &a[i].s, &a[i].a, &a[i].b);
do
{
int flag = 1;
for (int i = 1; i <= m; i++)
{
memset(vis, 0, sizeof vis);
int cnt1 = 0, cnt2 = 0;
int B = a[i].b;
int A = a[i].a;
for (int j = 0; j < n; j++)
if (a[i].s[j] == num[j] + '0') //判断有多少个相同的数字
++cnt1;
else
vis[a[i].s[j] - '0']++; //存提示串中有但是跟目标串不同的数字;
for (int j = 0; j < n; j++)
if (vis[num[j]])//若有该数字,但位置不同
++cnt2;
if (cnt1 != A || cnt2 != B) //进行判断是否满足条件
{
flag = 0;
break;
}
}
if (flag == 1)
{
for (int i = 0; i < n; i++)
cout << num[i];
cout << endl;
break;
}
} while (next_permutation(num, num + 10));
return 0;
}