Codeforces 950 C. Zebras
http://codeforces.com/contest/950/problem/C
题意:
给出一个01序列,问能否将这个序列分为若干个0开头0结尾的序列
输出方案
如果有解,几个1能在一个序列就在一个序列 一定可以找到解
因为0可以单独1个序列,1必须要依托于0
2个1如果分开 要4个0,连起来要3个0
暴力的做法就是:
如果当前是0,扫一遍已有序列,如果有1结尾的就把这个0放到那个1的后面
没有以1结尾的序列,新建一个序列
如果当前是1,扫一遍已有序列,如果有0结尾的就把这个1放到那个0的后面
没有以0结尾的就无解
极限复杂度是n^2 的
怎么优化?
用vector,cnt记录下一个0要放在哪个vector
如果是0就放在这个cnt所在的vector,cnt++
如果是1那就放到cnt-1所在的vector,先--cnt,再放1
#include<cstdio> #include<vector> #include<cstring> using namespace std; #define N 200005 char s[N]; vector<int>V[N]; int main() { scanf("%s",s+1); int len=strlen(s+1); if(s[1]=='1') { printf("-1"); return 0; } int cnt=0,tot=0; for(int i=1;i<=len;++i) { if(s[i]=='0') V[cnt++].push_back(i); else V[--cnt].push_back(i); if(!cnt && s[i+1]=='1') { printf("-1"); return 0; } tot=cnt>=tot ? cnt : tot; } for(int i=0;i<tot;++i) if(s[V[i][V[i].size()-1]]=='1') { printf("-1"); return 0; } printf("%d",tot); int siz; for(int i=0;i<tot;++i) { siz=V[i].size(); printf("\n%d",siz); for(int j=0;j<siz;++j) printf(" %d",V[i][j]); } return 0; }