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;
}