2.圆桌游戏
【问题描述】
有一种圆桌游戏是这样进行的:n个人围着圆桌坐成一圈,按顺时针顺序依次标号为1号至n号。对1<i<n的i来说,i号的左边是i+1号,右边是i-1号。1号的右边是n号,n号的左边是1号。每一轮游戏时,主持人指定一个还坐在桌边的人(假设是i号),让他向坐在他左边的人(假设是j号)发起挑战,如果挑战成功,那么j离开圆桌,如果挑战失败,那么i离开圆桌。当圆桌边只剩下一个人时,这个人就是最终的胜利者。
事实上,胜利者的归属是与主持人的选择息息相关的。现在,你来担任圆桌游戏的主持人,并且你已经事先知道了对于任意两个人i号和j号,如果i向j发起挑战,结果是成功还是失败。现在你想知道,如果你可以随意指定每轮发起挑战的人,哪些人可以成为最终的胜利者?
【输入】
第一行包含一个整数n,表示参加游戏的人数;
接下来n行,每行包含n个数,每个数都是0或1中的一个,若第i行第j个数是1,表示i向j发起挑战的结果是成功,否则表示挑战结果是失败。第i行第i列的值一定为0。
【输出】
一行,包含若干个数,表示可能成为最终胜利者的玩家的标号。标号按从小到大的顺序输出,相邻两个数间用1个空格隔开。
【输入输出样例1】
game.in |
game.out |
3 0 1 0 0 0 1 0 1 0 |
1 3 |
见选手目录下的game / game1.in与game / game1.out
【输入输出样例1说明】
先指定2号向3号发起挑战,3号离开;再指定1号向2号发起挑战,2号离开。此时1号是最终胜利者。
先指定1号向2号发起挑战,2号离开;再指定1号向3号发起挑战,1号离开。此时3号是最终胜利者。
无论如何安排挑战顺序,2号都无法成为最终胜利者。
【输入输出样例2】
见选手目录下的game / game2.in与game / game2.out
【数据规模与约定】
对于30%的数据,n≤7
对于100%的数据,n≤100
暴力30;
搜索,二进制模拟状态,每次枚举对战的两方,直到只剩一人。

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000010 #define ll long long using namespace std; int n; int on[120][120]; bool ok[110]; inline void dfs(int line) { // printf("%d ",line); int o=1; for(int i=1,j=1;i<=n;i++,o<<=1) { if((line&o)==o) { if(line-o>o) { int oo=o*2; for( j=i+1;j<=n;j++,oo<<=1) if((line&oo)==oo) break; if(on[i][j]) dfs(line-oo); else dfs(line-o); }else { int oo=1; for(j=1;j<=i;j++,oo<<=1) if((line&oo)==oo) break; // printf("\n") ; if(j<i) { if(on[i][j]) dfs(line-oo); else dfs(line-o); } else if(i==j) { ok[i]=1; } } } } return ; } int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&on[i][j]); dfs((1<<n )-1); for(int i=1;i<=n;i++) if(ok[i]) printf("%d ",i); return 0; }
满分做法: 区间dp
记f[i][j]为i和j两个人会相连,如果f[i][i+n]相连,则i可能是最终胜利者。
预处理,因为是个环我们用两倍的链来记,
f[i][i+1]一定会相连。
转移:
如果i,k,j能连接,且(i能打赢k 或 k挑战 j 失败) i和j就能连接。

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000010 #define ll long long using namespace std; int n; bool on[120][120]; bool f[210][210]; int s[210]; int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&on[i][j]); for(int i=1;i<=n;i++) s[i]=s[i+n]=i; for(int i=1;i<=n+n-1;i++) f[i][i+1]=1; for(int i=n+n-2;i>=1;i--) for(int j=i+2;j<=n+n;j++) for(int k=i+1;k<j;k++) if(f[i][k]&&f[k][j]&&(on[s[i]][s[k]]||!on[s[k]][s[j]]) ) { f[i][j]=1; break; } for(int i=1;i<=n;i++) if(f[i][i+n]) printf("%d ",i); return 0; }
小样例:
输入 3
1 1 1
1 1 1
1 1 1
输出 1 2 3
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App