思路
也是很唐的题。跟 Ad-hoc 爆了。
先手确实很劣,但如果先手连 不就变成后手了吗!
模仿人机操作。如果它连 ,那你就连 ,多得一分;否则它连 ,你就找一个得分最大的 ,有概率亏分。
但是人机在最后还比你多一步,而你第一步 虽然不亏但也没赚。所以第一步选 ,一个比较靠边但可以让人机更多的选 让你扩大优势的位置。取 有 的胜率。
然后你破防去看 std。
不妨更人机一点。在第一步之后,你也在最优的里面乱选。虽然这样你每一轮的得分不减,但是人机最后一步的得分大大增加,这样只有 的胜率。
但是 std 声称,同为最大得分的选择,更靠右的更有优势。感觉上也很是这样,因为你最终的目的在于减少人机最后一步的得分,而你最开始选在靠右的位置。然后就有 的胜率了???
code
int n;
int a[maxn][maxn];
void upd(int u,int v){
for(int i=1;i<=2*n;i++){
for(int j=1;j<=2*n;j++){
if(u==i||v==j)a[i][j]=-inf;
else a[i][j]+=((i-u)*(j-v)<0);
}
}
}
pii que(){
pair<int,pii> mx={0,{-2*n,-2*n}};
for(int i=1;i<=2*n;i++){
for(int j=1;j<=2*n;j++)mx=max(mx,{a[i][j],{-i,-j}});
}
return {-mx.se.fi,-mx.se.se};
}
pii ask(int u,int v){
cout<<u<<" "<<v<<endl;
upd(u,v);
u=read(),v=read();
upd(u,v);
return {u,v};
}
void work(){
memset(a,0,sizeof(a));
int x=10;
pii p=ask(x,x);
for(int i=2;i<=n;i++){
p=que();
p=ask(p.fi,p.se);
}
read();
}