CDQZ_Training 2012-5-24 词编码
题目描述地址:http://cdqz.openjudge.cn/noip/1009/
摘要:
一个发送机可以通过一条隧道发送一些以二进制代码组成的单词。,在其尽头的接收机可以使用特殊技术恢复到最初的单词。每个单词最初都由0和1组成。所有的单词最初长上簦都为n(4≤N ≤1000)。当穿过隧道之后单词可能发生以下几种情况之一:
(1)任意(一个)0被1取代
(2)任意(一个)符号被删除
(3)一个符号(0或1)被插入到任何位置
(4)不改变
我们知道最初的单词都具有以下性质:有1的位置号的总和是N+1的倍数,或者是0。
【input】
N和转换后的单词,每个单词占一行。单词数不大于2001.不会有其它任何东西,除了一些空格与空行,
【Output】
你的程序应该打印输出原始序列的词,注意换行。
若有多解,操作4优先,不行则按操作1,2,3优先。同一操作,按操作位置最先的优先。同一操作,按操作位置最先的优先(从左到右数起l,2,3,…N),还有操作2时,被删数列,先在被删数列添0,不行再添l。
如果没答案输出-1
【Sample input】
4
0000
011
1011
11011
【Sample Output】
0000
0110
1001
1111
这道题其实很简单的,只是一个简单的模拟罢了。唯一需要注意的就是时间复杂度的问题。我最开始是纯裸的,完全没有加优化,惨痛T掉3个点……下来想了一下,其实这道题用前缀和是相当容易的。
设a[i]表示处理后的串中从第i位开始的1的总数,先计算出1的位置的编号和,如果可行直接输出,否则判断位数。
1.如果位数为n-1,则肯定是删除了一位,此时枚举下标i,如果第i位上插入一个0,则和增加a[i],1的话就增加a[i]+i+1,一旦成功就输出,如果所有位置的插入都不成功,就输出-1.
2.位数为n,则肯定有一个1是被0取代了。枚举下标i,第i位上将1变成0后将和减去i+1,成功就直接输出,否则输出-1.
3.位数为n+1,则肯定增加了一位,此时枚举下标i(该删除的位),删除第i位只需将和减去a[i](i位上为0),a[i]+i(i位上为1),成功就输出,都不成功输出-1。
注意事项:
1.C++中字符串是零索引的,但是题目中却要求一索引。
2.字符串总数不定!!!不是n!!
3.求和其实有很多种方法,比如树状数组(我当时也想过,但是没写出来)。
4.那substr什么的太不稳定了,还是for一遍吧!(复杂度差不多)
废话说了一堆,最后我想吐槽几句标程,神马意思!!!!没加任何优化!!!!跑得飞快!!!!这不科学!!!!
代码:
View Code
1 #include<iostream> 2 #include<fstream> 3 #include<string> 4 5 using namespace std; 6 7 string s; 8 int n,len,sbwhc[2012]; 9 10 int main() 11 { 12 ifstream cin("word.in"); 13 ofstream cout("word.out"); 14 15 cin>>n; 16 while(cin>>s) 17 { 18 int k=0; 19 len=s.length(); 20 memset(sbwhc,0,sizeof(sbwhc)); 21 22 sbwhc[len]=0; 23 for(int i=len-1;i>=0;i--) 24 if(s[i]=='1') sbwhc[i]=sbwhc[i+1]+1; 25 else sbwhc[i]=sbwhc[i+1]; 26 27 for(int i=0;i<len;i++) 28 if(s[i]=='1') k+=i+1; 29 30 if(k%(n+1)==0&&len==n) 31 { 32 cout<<s<<endl; 33 continue; 34 } 35 36 if(len==n) 37 { 38 bool f=false; 39 for(int i=0;i<len;i++) 40 { 41 if(s[i]=='1') 42 if((k-i-1)%(n+1)==0) 43 { 44 f=true; 45 s[i]='0'; 46 cout<<s<<endl; 47 break; 48 } 49 } 50 if(!f) cout<<-1<<endl; 51 continue; 52 } 53 54 if(len<n) 55 { 56 bool f=false; 57 for(int i=0;i<=len;i++) 58 { 59 if((k+sbwhc[i])%(n+1)==0) 60 { 61 f=true; 62 for(int j=0;j<i;j++) cout<<s[j]; 63 cout<<"0"; 64 for(int j=i;j<len;j++) cout<<s[j]; 65 cout<<endl; 66 break; 67 } 68 69 if((k+sbwhc[i]+i+1)%(n+1)==0) 70 { 71 f=true; 72 for(int j=0;j<i;j++) cout<<s[j]; 73 cout<<"1"; 74 for(int j=i;j<len;j++) cout<<s[j]; 75 cout<<endl; 76 break; 77 } 78 } 79 if(!f) cout<<-1<<endl; 80 continue; 81 } 82 83 if(len>n) 84 { 85 bool f=false; 86 for(int i=0;i<len;i++) 87 { 88 if(s[i]=='0') 89 if((k-sbwhc[i])%(n+1)==0) 90 { 91 f=true; 92 s.erase(i,1); 93 cout<<s<<endl; 94 break; 95 } 96 97 if(s[i]=='1') 98 if((k-sbwhc[i]-i)%(n+1)==0) 99 { 100 f=true; 101 s.erase(i,1); 102 cout<<s<<endl; 103 break; 104 } 105 } 106 107 if(!f) cout<<-1<<endl; 108 continue; 109 } 110 } 111 return 0; 112 }

浙公网安备 33010602011771号