[bzoj4796][CERC2016]Key Knocking_乱搞
Posted shurak
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj4796][CERC2016]Key Knocking_乱搞相关的知识,希望对你有一定的参考价值。
Key Knocking bzoj-4796 CERC-2016
题目大意:描述没有题面短系列..题目链接
注释:$1le nle 10^5$。
想法:
乱搞稳AC。考试的时候调试信息又一次杀死了我...
我们考虑:因为总长度是$3n$,要求答案不小于$2n-1$,所以我们期望每$3$个数都贡献$2$,而且最多对于每$3$个数更改一次。
分类讨论一下:
我们只需考虑$0$开头的三元组($1$开头的同理)
如果是$001$,我们动后两位,变成$010$,贡献为$2$,以此类推。
$010$不动
$011 ightarrow101$。
$000$的话我们判断一下:
如果这个三元组的前一个数是$0$,我们就把它变成$110$,反之我们将它变成$011$,这样我们仍然会让这个三元组对答案造成2的贡献。
如果这个三元组在开头,我们就把前两位取反即可。因为题目中自动给定了一个权值,我们把那个权值送给第一个三元组即可。
最后,附上丑陋的代码... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; char s[300010]; int a[300010]; // int s[300010]; int cnt; inline void SP(int x) { if(s[x]==‘0‘) s[x]=‘1‘; else if(s[x]==‘1‘) s[x]=‘0‘; if(s[x+1]==‘1‘) s[x+1]=‘0‘; else if(s[x+1]==‘0‘) s[x+1]=‘1‘; } int main() { // freopen("key.in","r",stdin); // freopen("key.out","w",stdout); scanf("%s",s+1); int k=strlen(s+1); for(int i=1;i<=k-2;i+=3) { if(s[i]==‘0‘&&s[i+1]==‘0‘&&s[i+2]==‘1‘) a[++cnt]=i+1,SP(i+1); // if(s[i]==‘0‘&&s[i+1]==‘1‘&&s[i+2]==‘0‘) a[++cnt]=i; if(s[i]==‘0‘&&s[i+1]==‘1‘&&s[i+2]==‘1‘) a[++cnt]=i,SP(i); if(s[i]==‘1‘&&s[i+1]==‘0‘&&s[i+2]==‘0‘) a[++cnt]=i,SP(i); // if(s[i]==‘1‘&&s[i+1]==‘0‘&&s[i+2]==‘1‘) a[++cnt]=i; if(s[i]==‘1‘&&s[i+1]==‘1‘&&s[i+2]==‘0‘) a[++cnt]=i+1,SP(i+1); if(s[i]==‘0‘&&s[i+1]==‘0‘&&s[i+2]==‘0‘) { if(i==1) a[++cnt]=i; else if(s[i-1]==‘0‘) a[++cnt]=i,SP(i); else a[++cnt]=i+1,SP(i+1); } if(s[i]==‘1‘&&s[i+1]==‘1‘&&s[i+2]==‘1‘) { if(i==1) a[++cnt]=i; else if(s[i-1]==‘1‘) a[++cnt]=i,SP(i); else a[++cnt]=i+1,SP(i+1); } } printf("%d ",cnt); for(int i=1;i<=cnt;i++) { printf("%d ",a[i]); } return 0; }
小结:这种题多做吧!
以上是关于[bzoj4796][CERC2016]Key Knocking_乱搞的主要内容,如果未能解决你的问题,请参考以下文章
dpluoguP4796 关于图 想不到是状压dp (┬_┬)
bzoj 1552: [Cerc2007]robotic sort
bzoj 1552: [Cerc2007]robotic sort.