您的位置:首页 > 其它

Testing Round #13 C. Interactive Bulls and Cows (Hard) 枚举

2017-01-11 02:19 225 查看
题意:给定一个隐藏0-9组成的各个位置不同的4位字符串。每次猜测一个数字,系统返回bulls:位置对且值对的数字的个数;cows:位置不对但是值对的个数,且多个值对算一个。如:1234 与 2222 bulls=1,cows=0。

总共有5040种可能,每次猜测的时候:

1.尝试5040种中每一种可能,使得在当前可能的答案中,返回的bulls和cows的数量的最坏的情况最小。即每次保证排除足够多的答案。

2.更新当前的可行答案。即将可行答案与猜测的4位数比对bulls与cows,若与系统返回值不同,则不可能是正确答案。

直至系统返回4 0退出。

代码中:v1代表可行答案,v2表示5040种合法字符串。

#include <bits/stdc++.h>
using namespace std;
typedef unsigned int uii;
const int inf=0x3f3f3f3f;
int n1,n2,cnt[5][5],t2,tr,c,b;
vector<string> v1,v2,v3;
set<char> stc;
set<string> st;
string str;
char s[5];
bool v[10];
void pre() {
for (int i=123;i<=9999;++i) {
stc.clear();
s[3]=i%10+'0';
s[2]=i/10%10+'0';
s[1]=i/100%10+'0';
s[0]=i/1000%10+'0';
for (int j=0;j<4;++j)
stc.insert(s[j]);
if (stc.size()==4) {
v1.push_back(s);
v2.push_back(s);
}
}
}
bool fb() {
st.clear();
for (uii i=0;i<v1.size();++i)
st.insert(v1[i]);
t2=inf;
for (uii i=0;i<v2.size();++i) {
tr=0;
memset(v,0,sizeof v);
memset(cnt,0,sizeof cnt);
for (int j=0;j<4;++j)
v[v2[i][j]-'0']=1;
for (uii j=0;j<v1.size();++j) {
n1=n2=0;
for (int k=0;k<4;++k) {
if (v[v1[j][k]-'0'])
++n2;
if (v1[j][k]==v2[i][k])
++n1;
}
n2-=n1;
++cnt[n1][n2];
}
for (int j=0;j<=4;++j)
for (int k=0;k<=4;++k)
tr=max(tr,cnt[j][k]);
if (t2>tr) {
t2=tr;
str=v2[i];
} else if (t2==tr&&st.find(v2[i])!=st.end())
str=v2[i];
}
cout<<str<<endl;
fflush(stdout);
scanf("%d%d",&b,&c);
if (b==4)
return false;
v3.clear();
memset(v,0,sizeof v);
for (int j=0;j<4;++j)
v[str[j]-'0']=1;
for (uii j=0;j<v1.size();++j) {
n1=n2=0;
for (int k=0;k<4;++k) {
if (v[v1[j][k]-'0'])
++n2;
if (v1[j][k]==str[k])
++n1;
}
n2-=n1;
if (n1==b&&n2==c)
v3.push_back(v1[j]);
}
v1=v3;
return true;
}
int main()
{
pre();
while (fb()) {}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: