• [CodeForces950C]Zebras


    Description

    题目地址: Codeforces

    题意:给你一串只含01的字符串,判断能否将字符串分为k个子序列,使得子序列满足以下条件:

    1. 开头和结尾都是0
    2. 相邻的2个数是01或者10

    如0, 010, 01010 是合法的,1, 0110, 0101不合法

    要求输出方案

    (k可以为任意正整数,评测用SPJ)

    Solution

    我们发现,0可以单独为一组,那么只要匹配完所有的1剩下的0全单独算就行了

    对于方案可以用vector储存,关键在于如何划分子序列

    开一个指针变量p和一个方案数cnt,p指向一个序列,且保证当前p序列的最后面是0

    现在依次考虑每个数字

    如果当前数字是0并且p==cnt那么直接新开一个序列,否则把这个0放到p+1的序列中,且++p,这里因为p<cnt所以p+1的序列中必定结尾为1

    如果数字是1就把这个1直接放在当前p的序列中,然后p--,这里保证当前序列结尾是0,且p-1的序列结尾是0

    简单来说,保证结尾为1的序列全在p的后面,前面(包括p)的序列结尾都是0

    方法挺巧妙的,时间复杂度为O(n)

    Code

    #include <cstdio>
    #include <vector>
    #include <ctype.h>
    using namespace std;
    
    vector<int> Ans[200010];
    int p,cnt,n=1;
    
    int main(){
    	for(char ch=getchar();isdigit(ch);ch=getchar(),n++)
    		if(ch=='1'){
    			if(!p){printf("-1
    ");return 0;}//1过多的情况
    			Ans[p--].push_back(n);
    		}else if(p==cnt) Ans[p=++cnt].push_back(n);
    		else Ans[++p].push_back(n);
    	if(p<cnt){printf("-1
    ");return 0;}//0过多的情况
    	printf("%d
    ",cnt);
    	for(int i=1;i<=cnt;++i){
    		printf("%d ",Ans[i].size());
    		for(int j=0;j<Ans[i].size();++j)
    			printf("%d ",Ans[i][j]);
    		printf("
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    nyoj 19擅长排列的小明 (DFS)
    POJ 1321棋盘问题
    线段树与树状数组草稿
    组合博弈入门知识汇总
    组合博弈入门(题目练习及代码解析)
    pandas 连接数据库直接查表建立dataframe。loc,sort_values数据清洗操作
    Django 项目内利用ORM直接运行脚本读库
    Pandas库中的DataFrame
    利用pandas对numpy数组进行简单的科学计算
    进程池 爬去梨视频 视频资源
  • 原文地址:https://www.cnblogs.com/void-f/p/8536188.html
Copyright © 2020-2023  润新知