codeforce469DIV2——C. Zebras
题意
0, 010, 01010 这一类的01交替且开头和结尾都为0的序列被称为zebra序列。给出一段01序列,尝试能否把他分为k个子序列使得每个子序列都是zebra序列。
分析
这个题应该算是水题把,但是确实把我卡了。
一开始暴力找在序列中找1,然后分别往前往后各找一个0。但是最坏情况到O(n^2),TLE在第八组。然后我尝试了各种Set,vector,二分之类的瞎搞结果一直都没把复杂度降下来一直T在第八组绝望了。
赛后看其他人的代码发现··可以O(n)扫一遍,当s[i]是0的时候找加入最后一个是1的方案,若是1则加入最后一个是0的方案。如果没有合适的方案,就新开一个。可以用优先队列或者set搞
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 #include <queue> 6 #include <vector> 7 using namespace std; 8 const int maxn=200000+10; 9 char s[maxn]; 10 priority_queue<int,vector<int>,greater<int> >q0,q1; 11 vector<int>Q[maxn]; 12 int n,p; 13 int main(){ 14 scanf("%s",s+1); 15 n=strlen(s+1); 16 p=0; 17 bool ok=1; 18 for(int i=1;i<=n;i++){ 19 if(s[i]=='1'){ 20 if(q0.empty()){ 21 ok=0; 22 break; 23 } 24 int tmp=q0.top(); 25 q0.pop(); 26 Q[tmp].push_back(i); 27 q1.push(tmp); 28 }else{ 29 if(q1.empty()){ 30 p++; 31 Q[p].push_back(i); 32 q0.push(p); 33 }else{ 34 int tmp=q1.top(); 35 q1.pop(); 36 Q[tmp].push_back(i); 37 q0.push(tmp); 38 } 39 } 40 } 41 if(!ok||!q1.empty()){ 42 printf("-1"); 43 return 0; 44 } 45 printf("%d\n",p); 46 for(int i=1;i<=p;i++){ 47 printf("%d ",Q[i].size()); 48 for(int j=0;j<Q[i].size();j++) 49 printf("%d ",Q[i][j]); 50 printf("\n"); 51 } 52 return 0; 53 }