Language:Default Hang or not to hang
Time Limit: 1000MS | | Memory Limit: 10000K | Total Submissions: 871 | | Accepted: 226 |
Description Little Tom is learning how to program. He has just written some programs but is afraid to run them, because he does not know if they will ever stop. Please write a program to help him. This task is not as easy as it may seem, because Tom's programs are possibly not deterministic. Given a program written by Tom, your program should tell him whether his program can stop and if so, what is the shortest possible time before it stops.
Tom's computer consists of 32 1-bit registers and the program consists of n instructions. The registers are numbered from 0 to 31 and the instructions are numbered from 0 to n-1.
Below, MEM[a] stands for the contents of the a-th register, 0 <= a, b < 32, 0 <= x < n, 0 <= c <= 1.
The instruction set is as follows:
Instruction | Semantics | AND a b OR a b XOR a b NOT a MOV a b SET a c RANDOM a JMP x JZ x a STOP | MEM[a] := MEM[a] and MEM[b] MEM[a] := MEM[a] or MEM[b] MEM[a] := MEM[a] xor MEM[b] MEM[a] := not MEM[a] MEM[a] := MEM[b] MEM[a] := c MEM[a] := random value (0 or 1) jump to the instruction with the number x jump to the instruction with the number x if MEM[a] = 0 stop the program |
The last instruction of a program is always STOP (although there can be more than one STOP instruction). Every program starts with the instruction number 0. Before the start, the contents of the registers can be arbitrary values. Each instruction (including STOP) takes 1 processor cycle to execute. Task Write a program that:
reads the program, computes the shortest possible running time of the program, writes the result. Input The first line of the input contains an integer n (1 <= n <= 16) being the number of instructions of the program. Each of the next n lines contains one instruction of the program in the format given above. You may assume that the only white characters in the program are single spaces between successive tokens of each instruction. Output The first and only line of the output should contain the shortest possible running time of the program, measured in processor cycles. If the program cannot stop, output should contain the word HANGS. Sample Input 5
SET 0 1
JZ 4 0
RANDOM 0
JMP 1
STOP
Sample Output 6
Source Central Europe 2003 题意:给你n种命令,最多32个寄存器,问可能的最少的执行命令次数,使程序终止。 坑点:每个寄存器的初始值是随机的(0或者1) 思路:刚看到这题的时候以为每个寄存器的值为整数,毫无头绪,看大佬的博客才发现看错题意了,因为SET a c 说了c的值为0或1,所以每个寄存器的初始值为0或者1,直接把每个寄存器对应一个二进制位就行了。 JZ语句处理的话,只需要管跟a直接或间接相关的寄存器就可以了,因为总共16条语句,其中最后一条是STOP,那么去掉JZ之后还剩14条语句,说明最多有15个寄存器跟JZ有关,其他无关的寄存器就不用管了,记录一下需要管的寄存器就行,然后搜索的时候枚举二进制位寄存器的值放进队列,按照题目所给的语句进行操作就就可了。遇到random语句直接把该寄存器对应位置转换成二进制就行了。 顺便提供一些大佬造的数据 #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #include<vector> using namespace std; #define N 35 #define M 1<<15 #define inf ((1<<16)-1) vector<int> p[N]; char ch[20][20]; int a[20],b[20],d[20],du[N],c[N]; int vis[20][M]; int n,m,tot; typedef struct { int u,v,t; }node; void dfs(int x) { int i,j,k; k=p[x].size(); for(i=0;i<k;i++) { j=p[x][i]; if(du[j]==0) { du[j]=1; d[j]=tot++; dfs(j); } } } void bfs() { int i,j,k,ans=-1; memset(vis,0,sizeof(vis)); queue<node> q; node s,e; s.v=1; s.t=1; for(i=0;i<=(1<<tot);i++) { s.u=i; vis[1][i]=1; q.push(s); } while(!q.empty()) { s=q.front(); q.pop(); if(s.v>n) continue; if(ch[s.v][0]=='S'&&ch[s.v][1]=='T') { ans=s.t; break; } if(ch[s.v][0]=='J'&&ch[s.v][1]=='M') { e.v=a[s.v]+1; e.u=s.u; e.t=s.t+1; if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } continue; } if(ch[s.v][0]=='J'&&ch[s.v][1]=='Z') { k=((s.u>>(d[b[s.v]]))&1); if(k==0) e.v=a[s.v]+1; else e.v=s.v+1; e.u=s.u; e.t=s.t+1; if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } continue; } if(du[a[s.v]]==0) { e.u=s.u; e.v=s.v+1; e.t=s.t+1; if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } continue; } if(ch[s.v][0]=='R') { e.v=s.v+1; e.t=s.t+1; k=inf^(1<<d[a[s.v]]); e.u=s.u&k; if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } e.u=s.u|(1<<d[a[s.v]]); if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } continue; } j=((s.u>>d[a[s.v]])&1); k=((s.u>>d[b[s.v]])&1); if(ch[s.v][0]=='A') j=(j&k); if(ch[s.v][0]=='O') j=(j|k); if(ch[s.v][0]=='X') j=j^k; if(ch[s.v][0]=='N') j=j^1; if(ch[s.v][0]=='M') j=k; if(ch[s.v][0]=='S'&&ch[s.v][1]=='E') j=b[s.v]; if(j==0) { j=inf^(1<<d[a[s.v]]); e.u=s.u&j; } else if(j==1) e.u=s.u|(1<<d[a[s.v]]); e.t=s.t+1; e.v=s.v+1; if(vis[e.v][e.u]==0) { vis[e.v][e.u]=1; q.push(e); } } if(ans==-1) printf("HANGS\n"); else printf("%d\n",ans); } int main() { int i,j,k; while(scanf("%d",&n)!=EOF) { for(i=1;i<=32;i++) p[i].clear(); memset(du,0,sizeof(du)); m=0; tot=0; for(i=1;i<=n;i++) { scanf(" %s",ch[i]); if(ch[i][0]=='S'&&ch[i][1]=='T') continue; if(ch[i][0]=='R'||ch[i][0]=='N'||(ch[i][0]=='J'&&ch[i][0]=='M')) scanf("%d",&a[i]); else scanf("%d%d",&a[i],&b[i]); if((ch[i][0]=='J'&&ch[i][1]=='M')||ch[i][0]=='S'||ch[i][0]=='N'||ch[i][0]=='R') continue; if(ch[i][0]=='J') c[++m]=b[i]; else p[a[i]].push_back(b[i]); } for(i=1;i<=m;i++) if(du[c[i]]==0) { du[c[i]]=1; d[c[i]]=tot++; dfs(c[i]); } bfs(); } return 0; } 12 SET 0 0 SET 1 1 JZ 6 1 SET 2 1 RANDOM 1 JMP 2 SET 2 1 JZ 11 2 SET 0 1 RANDOM 2 JZ 7 2 STOP 16 SET 0 0 SET 1 0 SET 2 0 MOV 1 0 MOV 2 1 XOR 1 0 NOT 1 JZ 15 1 RANDOM 0 MOV 2 0 JZ 12 0 NOT 2 NOT 1 JZ 5 1 JMP 0 STOP 2 JZ 0 0 STOP 答案:13 18 2 |