【2016北京集训测试赛(七)】自动机 (思考题)
Time Limit: 1000 ms Memory Limit: 256 MB
Description
Solution
这是一道看起来令人毫无头绪的题,然而确实十分简单巧妙TAT。
题目要求所有点执行相同指令后都回到初始状态。
我们先来考虑只有两种状态的情况:初始状态与另一个状态。
这样,我们可以通过一个二元记忆化深搜,来得到一种方案A,使得回到,且回到。如果这个方案都不存在,那么此时无解。
现在我们知道,执行方案A后,与合并为一个了!那么我们对全局都执行方案A,可以发现至少会有包括在内的若干个状态被合并为。
因此在的次数里,我们可以按照下列步骤逐个合并状态:
- 对与任意一个状态进行深搜,得到一个方案。如果方案不存在,则无解。
- 对全局模拟此方案,合并相同的节点,回到1.直到只剩下
答案是?所有方案连在一起输出就好啦。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=101; 4 int n,m,ch[N][26]; 5 int size,lis[2000010],st[2000010],top,ans[2000010],len; 6 int vis[N][N]; 7 bool dfs(int x,int y){ 8 if(x==0&&y==0) return true; 9 if(vis[x][y]) return false; 10 vis[x][y]=1; 11 for(int i=0;i<m;i++){ 12 st[++top]=i; 13 if(dfs(ch[x][i],ch[y][i])) return true; 14 st[top--]=0; 15 } 16 return false; 17 } 18 int main(){ 19 scanf("%d%d",&n,&m); 20 for(int i=0;i<n;i++) 21 for(int j=0,x;j<m;j++) 22 scanf("%d",&x), 23 ch[i][j]=x; 24 for(int i=1;i<=n;i++) lis[i]=i-1; 25 size=n; 26 while(size>1){ 27 memset(vis,0,sizeof vis); 28 top=0; 29 if(!dfs(0,lis[2])){ 30 printf("[impossible]\n"); 31 return 0; 32 } 33 for(int j=1;j<=top;j++){ 34 ans[len++]='a'+st[j]; 35 for(int i=1;i<=size;i++) 36 lis[i]=ch[lis[i]][st[j]]; 37 } 38 sort(lis+1,lis+1+size); 39 size=unique(lis+1,lis+1+size)-lis-1; 40 } 41 for(int i=0;i<len;i++) putchar(ans[i]); 42 }
标签:
乱搞的思考题
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· Huawei LiteOS基于Cortex-M4 GD32F4平台移植
· mysql8.0无备份通过idb文件恢复数据过程、idb文件修复和tablespace id不一致处