一个发送机可以通过一条隧道发送一些以二进制代码组成的单词。在其尽头的接收机可以使用特殊技术恢复到最初的单词。每个单词最初都由0和1组成。所有的单词最-初长度都为n(4≤N ≤l000)。当穿过隧道之后单词可能发生以下几种情况之一:
(1)任意(一个)0被1取代
(2)任意(一个)符号被删除
(3)一个符号(0或1)被插入到任何位置
(4)不改变
我们知道最初的单词都具有以下性质:有1的位置号的总和是N+1的倍数,或者是0.
Input
N和转换后的单词,每个单词占一行。单词数不大于2001,不会有其它任何东西,除了一些空格与空行。
Outpul
你的程序应该打印输出原始序列的词,注意换行: 。
若有多解,操作4优先,不行则按操作1,2,3优先。同一操作,按操作位置最先的优先(从左到右数起l,2,3,…N),还有操作2时,被删数列,先在被删数列添0,不行再添1。如果没答案输出-1
Sample Input
4
0000
011
1011
11011
Sample Output
0000
0110
1001
1111
水题……就是模拟,但是我在考场上看错题目以为有无限次操作,结果爆蛋了
其实只有一次操作。然后按它给的顺序找原串就行了
#include<cstdio> #include<cstring> inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,len,sum; char ch[2010]; int f[2010]; int main() { freopen("word,in","r",stdin); freopen("word.out","w",stdout); n=read(); while (scanf("%s",ch)!=EOF) { len=0;sum=0; while (ch[len]=='0'||ch[len]=='1') len++; memset(f,0,sizeof(f)); for (int i=len-1;i>=0;i--) { f[i]=f[i+1]; if (ch[i+1]=='1')f[i]++; } for (int i=0;i<len;i++) sum+=(ch[i]=='1')*(i+1); if (sum%(n+1)==0&&len==n) //step 4 { for (int i=0;i<len;i++) printf("%c",ch[i]); printf(" "); continue; } if (len==n) //step 1 { bool mrk=0; for (int i=0;i<len;i++) if (ch[i]=='1'&&(sum-i-1)%(n+1)==0) { for (int j=0;j<len;j++) if (i!=j)printf("%c",ch[j]); else printf("0"); printf(" "); mrk=1;break; } if (mrk) continue; } if (len<n) //step 2 { bool mrk=0; for (int i=0;i<=len;i++) if ((sum+f[i])%(n+1)==0) { for (int j=0;j<len;j++) { printf("%c",ch[j]); if(i==j) printf("0"); } printf(" "); mrk=1;break; } if (mrk) continue; for (int i=0;i<=len;i++) if ((sum+f[i]+i+1)%(n+1)==0) { for (int j=0;j<len;j++) { printf("%c",ch[j]); if (i==j) printf("1"); } printf(" "); mrk=1;break; } if (mrk) continue; } if (len>n) //step 3 { bool mrk=0; for (int i=0;i<len;i++) { int t=sum-f[i]-(ch[i]=='1')*(i+1); if (t%(n+1)==0) { for (int j=0;j<len;j++) if (i!=j) printf("%c",ch[j]); printf(" "); mrk=1;break; } } if (mrk) continue; } printf("-1 "); } }