CodeForces 578E Walking!
题意
略。
题解
好毒瘤啊,我最多就口胡第一问的样子吧。
第一问很显然(跟凤凰县探险队员一样显然),就是每次贪心选长度最大的满足条件的子序列,选不到就折返回来。所以折返的次数很明显就是选出子序列的个数 \(-1\)。
考虑第二问,很明显不能暴力拼接子序列,这样很容易被 hack。具体方法剩下的题解有讲。
注意到找到的子序列可以按照开头和结尾分成 \(4\) 类:LL,LR,RL 和 RR。
首先有一个性质:可以将所有的 LR 拼在一起得到一个更长的 LR,RL 同理。
接下来 LL 和 RR 有一个特殊的作用,就是将一段 LR 和一段 RL 拼起来,类似于 L...RL...LR...L 和 R...LR...RL...R。(这里两个字母中间三个点表示一段子序列)
但是有些时候,没有 LL 和 RR,但是有 LR 和 RL,这两段是无法拼起来的。难道我们就这样失败了吗?没有的事!
我们可以通过已经有的 LR 和 RL 自己造一个 LL 和 RR 出来。具体地话就是考虑 LR 与 RL 中最后一个位置的关系。然后最后一个位置小的那个序列把最后一个位置给大的那个,然后 LR 就变成了 LL,而 RL 就变成了 RR。
然后这题就做完了。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51;
ll n,tot,x,y,swp;
vector<ll>v[MAXN],vg[2],g[2][2];
char ch[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
int main()
{
scanf("%s",ch+1),n=strlen(ch+1);
for(register int i=1;i<=n;i++)
{
x=ch[i]=='R',vg[x^1].empty()?vg[x^1].push_back(++tot):(void)1;
y=vg[x^1].back(),v[y].push_back(i);
vg[x^1].pop_back(),vg[x].push_back(y);
}
printf("%d\n",tot-1);
for(register int i=1;i<=tot;i++)
{
g[v[i].size()&1][ch[v[i].back()]=='R'].push_back(i);
}
if(!g[0][0].empty()&&!g[0][1].empty()&&g[1][0].empty()&&g[1][1].empty())
{
x=g[0][0].back(),y=g[0][1].back();
v[x].back()<v[y].back()?1:(swap(x,y),swp=1);
v[x].push_back(v[y].back()),v[y].pop_back();
g[0][0].pop_back(),g[0][1].pop_back(),swp?swap(x,y):(void)1;
g[1][0].push_back(y),g[1][1].push_back(x);
}
if(g[1][0].size()!=g[1][1].size())
{
x=g[1][1].size()>g[1][0].size();
}
else
{
x=g[0][0].size()>g[0][1].size();
}
while(!g[0][x^1].empty())
{
for(register int i:v[g[0][x^1].back()])
{
printf("%d ",i);
}
g[0][x^1].pop_back();
}
while(!g[1][x].empty())
{
for(register int i:v[g[1][x].back()])
{
printf("%d ",i);
}
g[1][x].pop_back();
while(!g[0][x].empty())
{
for(register int i:v[g[0][x].back()])
{
printf("%d ",i);
}
g[0][x].pop_back();
}
x^=1;
}
}
CodeForces 578E Walking!的更多相关文章
- Codeforces.578E.Walking(构造)
题目链接 \(Description\) 给定一个长为\(n\)的足迹序列(只包含\(L,R\)两种字符),你需要\(LRLRLR...\)这样交替在\(L\)和\(R\)上走(第一步可以选择\(L\ ...
- Codeforces 1154D - Walking Robot - [贪心]
题目链接:https://codeforces.com/contest/1154/problem/D 题解: 贪心思路,没有太阳的时候,优先用可充电电池走,万不得已才用普通电池走.有太阳的时候,如果可 ...
- Codeforces Round #605 (Div. 3) B. Snow Walking Robot(构造)
链接: https://codeforces.com/contest/1272/problem/B 题意: Recently you have bought a snow walking robot ...
- Diagonal Walking v.2 CodeForces - 1036B (思维,贪心)
Diagonal Walking v.2 CodeForces - 1036B Mikhail walks on a Cartesian plane. He starts at the point ( ...
- Kuro and Walking Route CodeForces - 979C (树上DFS)
Kuro is living in a country called Uberland, consisting of nn towns, numbered from 11to nn, and n−1n ...
- codeforces 979 C. Kuro and Walking Route
C. Kuro and Walking Route time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- Codeforces Round #482 (Div. 2) C 、 Kuro and Walking Route(dfs)979C
题目链接:http://codeforces.com/contest/979/problem/C 大致题意 给出n个点,有n-1个边将他们链接.给出x,y,当某一路径中出现x....y时,此路不通.路 ...
- Codeforces Round #482 (Div. 2) :C - Kuro and Walking Route
题目连接:http://codeforces.com/contest/979/problem/C 解题心得: 题意就是给你n个点,在点集中间有n-1条边(无重边),在行走的时候不能从x点走到y点,问你 ...
- Codeforces Round #501 (Div. 3) 1015D Walking Between Houses
D. Walking Between Houses time limit per test 2 seconds memory limit per test 256 megabytes input st ...
随机推荐
- python数据结构实现(栈和链栈)
栈 class Stack: def __init__(self, limit: int 10): self.stack = [] self.limit = limit def __bool__(se ...
- Python对象的空间边界:独善其身与开放包容
导读:Python猫是一只喵星来客,它爱地球的一切,特别爱优雅而无所不能的 Python.我是它的人类朋友豌豆花下猫,被授权润色与发表它的文章.如果你是第一次看到这个系列文章,那我强烈建议,请先看看它 ...
- java实现详细的身份证验证、能正确验证身份证正确性
IdCardExpUtil.java package com.javazs.util; import java.text.ParseException; import java.text.Simple ...
- Python实现的数据结构与算法之基本搜索详解
一.顺序搜索 顺序搜索 是最简单直观的搜索方法:从列表开头到末尾,逐个比较待搜索项与列表中的项,直到找到目标项(搜索成功)或者 超出搜索范围 (搜索失败). 根据列表中的项是否按顺序排列,可以将列表分 ...
- 在程序开发中,++i 与 i++的区别在哪里?
哈哈哈! 从大学开始又忘了...蜜汁问题哈 参考来源:https://www.zhihu.com/question/19811087/answer/80210083 i++ 与 ++i 的主要区别有两 ...
- C/C++ typedef用法
原文来源:https://blog.csdn.net/superhoy/article/details/53504472 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同 ...
- matlab中colormap
来源:https://ww2.mathworks.cn/help/matlab/ref/colormap.html?searchHighlight=colormap&s_tid=doc_src ...
- Arduino 寻找I2C地址address
参考:http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/arduino-quick-tip-fin ...
- HTML & CSS & JavaScript 从一个表格到一个灰阶颜色表 01
工具1:HBuilder X 1.9.9.20190522 工具2:火狐浏览器 67.0.4 (64 位) 在开始之前,你需要了解一些基本的知识,不要求你能掌握,但是了解一下还是有益的: HTML 简 ...
- Java之线程池解析
线程池 目录 线程池 线程池概述 创建一个线程池并提交线程任务 线程池源码解析 参数认识 构造方法 提交任务 addWorker 执行任务 关闭线程池 线程池概述 什么是线程池 为什么使用线程池 线程 ...