Codeforces Round #469 (Div. 2) BC

题目链接

B题 解题思路:


给与n , m 让我们求出这两组中能组成多少相同的电报,比如样例中所说:
在这里插入图片描述
因此我们从头到尾遍历即可,然后最后时候需要判断是否需要 + 1,因为存在特殊的情况,一种包括n , m 都是 1 另一种包含不都是 1 那么肯定最后需要 + 1,因为没判断完全,而且两个信息段肯定是完全相同的(只是被拆散成一些部分)


代码:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef  long long ll;

ll ans[100010],res[100010];

int main(){
    ll n , m;
    scanf("%lld%lld",&n,&m);
    for (int i = 0; i < n; i ++) scanf("%lld",&ans[i]);
    for (int j = 0; j < m; j ++) scanf("%lld",&res[j]);
    int p = 1, q = 1;
    ll a = ans[0];
    ll b = res[0];
    int result = 0;
    while(p <= n  && q <= m ){ 
        if (a == b){
            result ++;
            if (p <= n - 1) a += ans[p ++]; // 如果超出范围 那么直接 break。
            else if (q <= m - 1) b += res[q ++];
            else {
                break;
            }
        }
        else if (a < b){  
            a += ans[p++];
        }
        else{
            b += res[q++];
        }
    }
    if (p != n  || q != m ) printf("%d\n",result + 1); // 如果有一个没有加完,那么肯定还会存在 因此需要 + 1
    else printf("%d\n",result);
    
    return 0;
}



题目链接

解题思路:


给与一个只有 01 字符串,然后规定,需要按照 0 ,010 ,0101010 这样的方法存入,问是否能够以这种形式存在,并且将其划分开,(从头到尾开始存)

我们可以将其看成一个二维数组,(哈希好像我也忘了),本题原理跟拉链法类似,都是如果是0,那么就存入,1的话寻找适当的位置进行存入,那么我们从下标为0开始,如果是0 ,我们将下标 + 1 然后将其存入,如果是1我们存入后再找前一位 (代码注释中存在),最后判断,如果他没有回到原来的位置,那么我们也应该输出 -1 ,因为最后的位置肯定为 0.


代码:


#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>

using namespace std;

typedef  long long ll;


char st[200010];

vector <int> ans[200010];

int main(){
    scanf("%s",st+1); // 下标从 1 开始的字符串
    int n = strlen(st + 1);
    int  x = 0;
    int mx = 0;
    for (int i = 1; i <= n; i ++){
        if (st[i] == '1'){  
            if(x == 0) { // 如果到达 下标为 0,如果还是 1,那么输出 -1
                puts("-1");
                return 0;
            }
            else{
                ans[x--].push_back(i); // 否则存入当前的位置,下标 --
            }
        }   
        else{
            ans[++x].push_back(i);  当前为0,回到下一位 存下标
        }
        mx = max(mx,x);
    }
    if (mx != x){ // 如果最后没回到最大位置 那么输出 -1
        puts("-1");
        return 0;
    }
    printf("%d\n",mx);
    for (int i = 1; i <= mx; i++){
        printf("%d",ans[i].size());
        for (int j = 0; j <ans[i].size();j++){
            printf(" %d",ans[i][j]);
        }
        puts("");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值