题目大意

将给定字符串分割成若干子序列(子序列:允许不相邻但按先后顺序选取若干字符构成的字符串),这些子序列要满足由01串构成且开始和结束字符必须为0。很显然每个字符只能出现在一个子序列中。
先输出你构造出的子序列的个数;
下面输出你构造的子序列,第一个数为子序列长度,后面跟着这个子序列每个字符对应于原字符串中的索引(从1开始),每行对应一个构造的子序列。
对输出的唯一限制是要求输出的字符索引为升序。

题解

思路1:大佬思路,对应代码1:
首先必然得存住答案才行,因此使用二维vectorans[i]就代表第i个子序列。
遇到0我们就就将0加入到当前的ans[cnt]中,并且++cnt;遇到1--cnt,将1加入到当前的ans[cnt]中。总而言之,遇到0cnt增加的ans中插入,遇到1cnt减小的ans中插入。
每次遇到1说明cnt要减小了,那我们就保存一下最大的cnt,表示构造的子序列的全部个数,但是如果最后遍历完字符串后的cnt与保存的最大值不一致就说明至少存在一个(ans中保存的)子序列的最后一元素为1,无法以0结尾。
至于为什么,你可以模拟一个过程试试,很容易理解的。
稍微举两种极端的情况:

  1. 最后结尾的0超级多,那么cnt会一直自加,显然最后cnt就是cnt的最大值。此时必然都覆盖住了。
  2. 最后没有0,即原字符串以1结尾,必然无法构造出答案,此时肯定存在至少一个(ans中保存的)子序列的结尾为1,也说明ans[cnt]上次为这个子序列是将末尾添加了个1,之后便没来过了,即’cnt < max(cnt)’,无解。

当然,我们不能忽略当cnt减到0的情况啊,1太多了cnt减到0也是无解。


思路2:我的思路,含思考过程,对应代码2:
先声明我看了上面大佬的题解。
第一个思考阶段:
首先我试着思考什么时候会输出-1
原字符串第一个或最后一个字符为1是一定不行的;
片面思考过后就觉得,可以先将连续的01划分为一段,只要保证连续的0的个数大于等于其相邻的两段的连续的1的个数的最大值即可,00101100并非无解,但是按我的方法判断就是无解了。
保存的话,我就用普通数组保存的,因为我没看到要先输出总的子序列个数,所以构成一个子序列就直接输出了,最后才发现是错的。
构造方法也存在问题,在这就不细说错误思路了。

第二个思考过程:
上面判断无解的方式错了,但我觉得这个题应该是可以先特判出无解的情况的(有些题直接判无解是比较难的)
思考了一会理解构造的本质了,可以理解为遇到一个1就是对前面0的消耗,因此遇到1我们要判断一下是否还剩下未被消耗的0,只有有0才能让1构成子序列。同时也要从后向前进行判断。
二维vector无疑了,现在的思路是每次遇到1插入第一个末尾为0的子序列中(对应的ans索引小者为第一个,后同),遇到0插入到第一个末尾为1的子序列中。
但是如何保存和更新“第一个末尾为0的子序列”和“第一个末尾为1的子序列”对应的索引呢?保存好说,那假如要是找到了,需要将原索引更新成新的第一个索引,怎么更新?遍历?疯了吧。
失败告终,看了大佬的题解。

第三个思考过程:
大佬的“蛇形插入法”(我真是起名鬼才)完美的解决了这个问题!
(我觉得这是个很好的思路,值得学习!)
因此,特判无解就采用了我自己的方式,而保存和输出正解用了大佬的方式。

代码1

#include<cstdio>
#include<vector>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 200000 + 5;
char str[maxn];
vector<int> G[maxn];
inline void fail(){ printf("-1");  exit(0); }
int main()
{scanf("%s", str);int n = strlen(str), cnt = 0, k = 0;for(int i = 0;i < n; ++i){if(str[i] == '0')  {G[cnt++].push_back(i + 1);}else{if(cnt == 0) fail(); G[--cnt].push_back(i + 1);       k = max(k, cnt);}}if(k >= cnt) fail();printf("%d\n", cnt);for(int i = 0;i < cnt; ++i){printf("%d ", G[i].size());for(int j = 0;j < G[i].size(); ++j) printf("%d ",G[i][j]);printf("\n");}return 0;
}

代码2

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;string str;
int a[N], cnt, cnt0, cnt1, flag, ff, cntleft, cntright;
vector<int> ans[N];int main()
{cin>>str;int n = str.length();str = '.' + str;// -1:if(str[1] == '1' || str[n] == '1') { puts("-1"); return 0; }for(int i = 1;i <= n;i ++) {int x = str[i] - '0';if(x == 0) {cnt0 ++;if(flag) a[++cnt] = cnt1, cnt1 = 0, flag = 0;} else {cnt1 ++;if(!flag) a[++cnt] = cnt0, cnt0 = 0, flag = 1;}}a[++cnt] = cnt0;for(int i = 1, j = cnt;i <= cnt;i ++, j --) {if(i&1) cntleft += a[i], cntright += a[j];else cntleft -= a[i], cntright -= a[j];if(cntleft < 0 || cntright < 0) { ff = 1; break; }}if(ff) {puts("-1"); return 0;}// not -1:cnt = 0;for(int i = 1;i <= n;i ++){if(str[i] == '0') ans[++cnt].push_back(i);else ans[cnt--].push_back(i);       }cout << cnt << endl;for(int i = 1;i <= cnt;i ++){cout << ans[i].size();for(int j = 0;j < ans[i].size();j ++) cout << ' ' << ans[i][j];puts("");}return 0;
}

CodeForces 949A Zebras相关推荐

  1. CodeForces 375D Tree and Queries

    传送门:https://codeforces.com/problemset/problem/375/D 题意: 给你一颗有根树,树上每个节点都有其对应的颜色,有m次询问,每次问你以点v为父节点的子树内 ...

  2. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

  3. 【codeforces 812C】Sagheer and Nubian Market

    [题目链接]:http://codeforces.com/contest/812/problem/C [题意] 给你n个物品; 你可以选购k个物品;则 每个物品有一个基础价值; 然后还有一个附加价值; ...

  4. CodeForces 获得数据

    针对程序的输出可以看见 CodeForces :当输入.输出超过一定字符,会隐藏内容 所以:分若干个程序进行输入数据的获取 1. 1 for (i=1;i<=q;i++) 2 { 3 scanf ...

  5. codeforces水题100道 第二十七题 Codeforces Round #172 (Div. 2) A. Word Capitalization (strings)...

    题目链接:http://www.codeforces.com/problemset/problem/281/A 题意:将一个英文字母的首字母变成大写,然后输出. C++代码: #include < ...

  6. CodeForces 595A

    题目链接: http://codeforces.com/problemset/problem/595/A 题意: 一栋楼,有n层,每层有m户,每户有2个窗户,问这栋楼还有多少户没有睡觉(只要一个窗户灯 ...

  7. codeforces A. Jeff and Digits 解题报告

    题目链接:http://codeforces.com/problemset/problem/352/A 题目意思:给定一个只有0或5组成的序列,你要重新编排这个序列(当然你可以不取尽这些数字),使得这 ...

  8. Codeforces Round #506 (Div. 3)

    Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...

  9. Codeforces Round #417:E. FountainsSagheer and Apple Tree(树上博弈)

    Codeforces Round #417:E. FountainsSagheer and Apple Tree(树上博弈) 标签: codeforces 2017-06-02 11:41 29人阅读 ...

  10. [题解]RGB Substring (hard version)-前缀和(codeforces 1196D2)

    题目链接:https://codeforces.com/problemset/problem/1196/D2 题意: q 个询问,每个查询将给你一个由 n 个字符组成的字符串s,每个字符都是 &quo ...

最新文章

  1. 干货丨计算机视觉必读:图像分类、定位、检测,语义分割和实例分割方法梳理(经典长文,值得收藏)
  2. 2011阿里巴巴集团实习生招聘笔试题 CC++
  3. 工业串口和网络软件通讯平台(SuperIO 2.1)更新发布
  4. 零云九歌小组KTV点歌系统简介
  5. 打开git界面_使用 Gitea 快速搭建私有 Git 版本控制服务
  6. Java实训项目13:GUI学生信息管理系统 - 实现步骤 - 创建应用程序类
  7. 程序员面试金典——17.6最小调整有序
  8. [C++/CLI编程宝典][7]基本概念
  9. SpringBoot 中使用 QuzartZ
  10. blackberry 9630CDMA写号教程
  11. 77---Python 计算Sin(x)的积分
  12. Oracle BI产品线
  13. java导出excel 打不开_java – 无法使用AbstractExcelView导出Excel工作表
  14. 3d虚拟VR实训教学软件制作
  15. (五证合一)法人和其他组织统一社会信用代码编码规则
  16. 分布式系统与计算机网络
  17. Guava之RateLimiter限流
  18. 送5本《Kafka权威指南》第二版
  19. 【题解】慈溪中学-8.14-T1
  20. Python数据科学包(六)-----数据可视化和例子

热门文章

  1. jQuery官网下载文档的步骤
  2. Zend Guard加密PHP项目图文分解教程,加密兼容PHP7.x
  3. SKU后台管理添加商品
  4. Note: the configuration keeps the entry point 'XXX', but not the descriptor class 'XXX'
  5. Vue简易图片手风琴组件,包含宽度适应(JS操作CSS实现)
  6. wep加密方式是什么_什么是WEP(有线等效保密)?
  7. 5-3 jmu-java-m05-使用Comparator接口排序 (10分)
  8. 计算机count是什么函数,计算机里COUNT是什么函数?怎么用的?好评!!
  9. 数据加工(一)-------数据抽取
  10. 2022年第七届IEEE云计算与大数据分析国际会议