[bzoj4796][CERC2016]Key Knocking_乱搞
Key Knocking bzoj-4796 CERC-2016
题目大意:描述没有题面短系列..题目链接
注释:$1\le n\le 10^5$。
想法:
乱搞稳AC。考试的时候调试信息又一次杀死了我...
我们考虑:因为总长度是$3n$,要求答案不小于$2n-1$,所以我们期望每$3$个数都贡献$2$,而且最多对于每$3$个数更改一次。
分类讨论一下:
我们只需考虑$0$开头的三元组($1$开头的同理)
如果是$001$,我们动后两位,变成$010$,贡献为$2$,以此类推。
$010$不动
$011\rightarrow101$。
$000$的话我们判断一下:
如果这个三元组的前一个数是$0$,我们就把它变成$110$,反之我们将它变成$011$,这样我们仍然会让这个三元组对答案造成2的贡献。
如果这个三元组在开头,我们就把前两位取反即可。因为题目中自动给定了一个权值,我们把那个权值送给第一个三元组即可。
最后,附上丑陋的代码... ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #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\n" ,cnt); for ( int i=1;i<=cnt;i++) { printf ( "%d\n" ,a[i]); } return 0; } |
小结:这种题多做吧!
| 欢迎来原网站坐坐! >原文链接<
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步