题目链接:http://codeforces.com/problemset/problem/401/C
题目意思:给出0和1的数目(分别为n和m个),问是否能构造一条同时满足连续两个0不能再一起和连续三个1不能在一起,并且长度为n+m的序列,不能输出-1。
首先需要知道什么时候不能构造出来。假设c0代表0的数目,c1表示1的数目。那么可以构造的条件是: c0-1 <= c1 <= 2c0+2
接着构造一条以0为开头和结尾的01交错,长度为2*n-1的序列。(即0101...10)。这时1的个数为n-1,0的个数为n。求出多出的1的个数,为m - n。
最后需要在这条序列中的0的位置输出110(本来序列除最后的0的前面都有一个1),这样输出会使得m-n个1相应地减少1。直至所有的m-n个1完全输出(即变为0),此时输出剩下的原始序列。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 using namespace std; 5 6 const int maxn = 1e6 + 5; 7 int a[2*maxn]; 8 9 int main() 10 { 11 int i, n, m; 12 while (scanf("%d%d", &n, &m) != EOF) 13 { 14 if (m < n-1 || m > 2*n+2) 15 printf("-1\n"); 16 else 17 { 18 for (i = 1; i <= 2*n-1; i++) //construct 19 { 20 if (i & 1) 21 a[i] = 0; 22 else 23 a[i] = 1; 24 } 25 int cnt = 0; // 统计输出的数量 26 int c1 = m - n; // 统计多出的1的个数 27 if (m + 1 == n) // 和构造的原始序列一样 28 { 29 for (i = 1; i <= 2*n-1; i++) 30 printf("%d", a[i]); 31 printf("\n"); 32 } 33 else 34 { 35 for (i = 1; i <= 2*n-1; i++) 36 { 37 if (a[i] == 0 && c1) 38 { 39 c1--; 40 printf("110"); 41 cnt += 3; 42 } 43 else if (c1 == 0 && cnt < n+m) 44 { 45 printf("%d", a[i]); 46 cnt++; 47 } 48 } 49 if (cnt != n+m) // 在最后补1 50 { 51 for (i = 1; i <= n+m-cnt; i++) 52 printf("1"); 53 } 54 printf("\n"); 55 } 56 } 57 } 58 return 0; 59 }