Codeforces Round #470 (rated, Div. 1, based on VK Cup 2018 Round 1) 923D 947D 948E D. Picking Strings
题:
OvO http://codeforces.com/contest/947/problem/D
923D 947D 948E
解:
记要改变的串为 P1 ,记目标串为 P2
由变化规则可得:
1. B -> AC -> AAB -> AAAC -> C ( 即 B -> C -> B )
2. AB -> AAC -> AAAB -> B (即 AB -> B )
3. B -> AC -> AB ( 即 B -> AB )
4. A -> BC -> BB ( 即 A -> BB )
(由规则1可得,B 与 C 等价,所以下文 C 全由 B代替)
那么对于一个串 S ,可以从这个串中提取 3 个特征,记这3个特征为 val0, val1, val2,
这3个特征的意义为:
对于串 S,把 S 串分成2个部分 S1, S2,其中 S2 是 S 的后缀,其内含字符全为 A,使 S2 长度尽可能长,记 S2 串长度为 val2 。S1 串为去掉 S2 后的部分,记 S1 串中非 A 字符的个数为 val1 。并且,如果 S1 串为空,记 val0=0,否则 val=1。
(接下去的思路就是转化 P1 中的 S1 与 S2,使其与 P2 中的 S1,S2 相同)
然后进行分类讨论,以下 5 种情况,P1 串无法转换为 P2 串(不具体证明)
1. (P1.val1 & 1) != (P2.val1 & 1)
2. P1.val1 > P2.val1
3. P1.val2 < P2.val2
4. P1.val1 == P2.val1 && (P1.val2 - P2.val2) % 3 != 0
5. P1.val0 == 0 && P1.val1 < P2.val1 && P1.val2 == P2.val2
其余情况,P1 均可以转化为 P2
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio> using namespace std; struct Val
{
int val0,val1,val2;
} ; const int M=1e5+44; char s[2][M];
int len[2],p[2][M],a[2][M],lst[2][M],b[2][M];
int lans,ans[M]; void init(int id)
{
int tmp;
scanf("%s",s[id]+1);
len[id]=strlen(s[id]+1);
for(int i=1;i<=len[id];i++)
if(s[id][i]=='A') p[id][i]=0;
else p[id][i]=1;
a[id][0]=b[id][0];
for(int i=1;i<=len[id];i++)
a[id][i]=a[id][i-1]+(p[id][i]==0),b[id][i]=b[id][i-1]+(p[id][i]==1);
tmp=0;
for(int i=1;i<=len[id];i++)
if(p[id][i]==1)
tmp=i,lst[id][i]=tmp;
else lst[id][i]=tmp;
} Val solve(int id,int li,int ri)
{
int tag=lst[id][ri],part0,part1,part2;
if(tag<li) tag=li-1,part0=0;
else part0=1;
part2=(a[id][ri]-a[id][tag]);
part1=(b[id][ri]-b[id][li-1]);
return Val{part0,part1,part2};
} bool check(Val tp0,Val tp1)
{
if((tp0.val1&1)!=(tp1.val1&1)) return false;
if(tp0.val1>tp1.val1) return false;
if(tp0.val2<tp1.val2) return false;
if(tp0.val1==tp1.val1 && (tp0.val2-tp1.val2)%3!=0) return false;
if(tp0.val0==0 && tp0.val1<tp1.val1 && tp0.val2==tp1.val2) return false;
return true;
} int main()
{
init(0),init(1);
int cas,li0,ri0,li1,ri1;
Val tp[2];
lans=0;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d%d%d",&li0,&ri0,&li1,&ri1);
tp[0]=solve(0,li0,ri0),tp[1]=solve(1,li1,ri1);
// cout<<tp[0]<<" "<<tp[1]<<endl;
if(check(tp[0],tp[1])) ans[++lans]=1;
else ans[++lans]=0;
}
for(int i=1;i<=lans;i++)
printf("%d",ans[i]);
return 0;
}
最新文章
- ESXi Install OpenWRT
- BZOJ1915: [Usaco2010 Open]奶牛的跳格子游戏
- 从零开始学习Node.js例子四 多页面实现数学运算 续一(使用connect和express框架)
- Java集合 之 Queue集合
- Object C学习笔记16-委托(delegate)
- mysql用户权限
- JAVA实例,求用户输入的整数是否是偶数
- 读取AD模拟分量
- mysql修改表、字段、库的字符集
- ubuntu杂记
- 理解和熟练运用js中的call及apply
- HTML5添加背景音乐
- JVM学习之对象的状态
- 设置某个类使用或者禁用ARC
- Maven的Archetype简介
- mysql 服务【安装】【启动】【停止】【卸载】【重置密码】
- 【题解】UVA11362 Phone List
- 配置Google Gmail分类和过滤器
- 【linux】linux查找功能
- CentOS增加用户到sudo用户组
热门文章
- Word F1~F12 功能快捷键用法大全
- 利用Python进行数据分析_Pandas_绘图和可视化_Matplotlib
- 利用Python进行数据分析_Numpy_基础_2
- PAT(B) 1006 换个格式输出整数(Java)
- 第十六章:网络IPC 套接字
- Scratch:海龟绘图(九)
- 第四讲,数据目录表之导入表,以及IAT表
- linux之find的使用
- 在论坛中出现的比较难的sql问题:6(动态行转列 考试科目、排名动态列问题)
- [JZOJ5465]道路重建--边双缩点+树的直径