codeforces C. Team 解题报告

题目链接: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 } 

 

     

转载于:https://www.cnblogs.com/windysai/p/3602792.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值