zoukankan      html  css  js  c++  java
  • UVALive 6256 LA 6256 Who wants to live forever?

    题意:给出一个只含01的字符串,然后用s(i-1) xor s(i+1)的结果去更新s(i),最后问能否将原串更新成全部为0的字符串。

    一拿到就觉得这应该是找规律题,经过简单的推理,可以得到这么一些结论:

    1.当字符串长度为1,3,7的时候,无论原串是什么,分别最多做1,3,7次操作,总能变成全部为0的串(YY:只要字符串的长度为2^n-1,无论原串是什么,总能变成全部为0的串)

    2.当字符串长度为偶数时,除非原串本身全为0,否则不可能将原串更新为全部为0的串(这个能证出来,倒着推一下就行了,给出一个长度为偶数且全为0的串,向上推一个可行的状态,让它不仅含有1而且还可以变成全部为0的,这是不可能的)

    3.当字符串长度为4n+1时,除非原串本身全为0或者为10101…………010101这样以1开始和结尾,中间01间隔的这样一种形式,否则不可能将原串更新为全部为0的串(还是跟上面一样倒推,可以推出来)

    4.当字符串长度为4n+3时,状态就比较多了,显然对于4n+1的所有情况是成立的,但是由10101…………010101这样的串,还可以往上推。这好像就没什么办法了。没办法就暴力打表(当然也是倒着推来打的表),打出来看下有什么规律。。但是打出来从字符串本身来看,真的找不到什么规律。但是有一个发现,当字符串长度n=11,19的时候,可行解一共是8个,当n=23的时候,可行解突然达到了128个。再然后,可以推出来(不是看出来,当然看也能看出来),所有长度为11的可行串,在4,8这两个位置上必须为0,且1-3和5-7这两个区间是关于4位置对称的,5-7和9-11这两个区间是关于8这个位置对称的,大概就是这样一种情况:acb0bca0acb。结合刚才的两点,又可以YY了:可行解一定是关于某些位置对称的,n=11,19的时候,可行解数是8=2^3,n=23的时候,可行解数=128=2^7,继续YY,长度为11的时候,可行解的只有abc的取值决定,abc各有两个取值,结果就是2的3次=8。要是这样的话,n=23的时候,应该关于8,16这两个位置对称,可行解应该是这样一种形式:abcdefg0gfedcba0abcdefg,可行解的只有abcdefg的取值决定,abcdefg各有两个取值,结果就是2的7次=128。那么这个对称的位置的取值究竟是由什么决定的,继续YY。(11+1)%(2^2)=0,(19+1)%(2^2)=0,(23+1)%(2^3)=0,也就是说,当字符串长度=4n+3的时候,要找一个最大的k,使得(4n+3+1)%(2^k)=0,那么这些对称的位置就是所有的0<(2^k)*t<4n+3(t为整数)的位置。

    以上是我们YY本题的全部过程。用这样的做法去交能AC也说明了这些YY的结果都是正确的。本题我们队集体YY了一小时,最后因为我的一个失误,在比赛的最后时刻没有A,就差了一行。。要是正式比赛出现这样的情况,是要吐血的。

    看到标程,彻底Orz了。。不管字符串长度是多少,他只用到了我上面写的第4条YY的那些规则就搞定了,不过后来我想想也对,只要满足第四条的对称规则就行。

    贴两份代码,一份自己写的,一份标程的

     1 #include <cstdio>
     2 #include <cstring>
     3 char S[200020];
     4 int main(){
     5     int T,len;
     6     scanf("%d",&T);
     7     while(T--){
     8         scanf("%s",S);
     9         len = strlen(S);
    10         if((len&(len+1)) == 0){
    11             puts("DIES");
    12             continue;
    13         }
    14         if((len&1) == 0){
    15             bool flag = 1;
    16             for(int i = 0;i < len;i++){
    17                 if(S[i] - '0' == 1){
    18                     flag = 0;
    19                     break;
    20                 }
    21             }
    22             if(flag)    puts("DIES");
    23             else        puts("LIVES");
    24             continue;
    25         }
    26         if(len % 4 == 1){
    27             bool flag = 1;
    28             for(int i = 0;i < len;i++){
    29                 if(S[i] - '0' == 1){
    30                     flag = 0;
    31                     break;
    32                 }
    33             }
    34             if(flag){
    35                 puts("DIES");
    36                 continue;
    37             }
    38             flag = 1;
    39             for(int i = 0;i < len;i++){
    40                 if((i&1) == 0 && S[i] - '0' != 1){
    41                     flag = 0;
    42                     break;
    43                 }
    44                 if((i&1) == 1 && S[i] - '0' != 0){
    45                     flag = 0;
    46                     break;
    47                 }
    48             }
    49             if(flag)    puts("DIES");
    50             else        puts("LIVES");
    51             continue;
    52         }
    53         if(len % 4 == 3){
    54             bool flag = 1;
    55             for(int i = 0;i < len;i++){
    56                 if(S[i] - '0' == 1){
    57                     flag = 0;
    58                     break;
    59                 }
    60             }
    61             if(flag){
    62                 puts("DIES");
    63                 continue;
    64             }
    65             flag = 1;
    66             int k = 1;
    67             int tmp = len+1;
    68             while((tmp&1) == 0){
    69                 k *= 2;
    70                 tmp >>= 1;
    71             }
    72             for(int i = k-1;i < len;i = i+k){
    73                 if(S[i] - '0' != 0){
    74                     flag = 0;
    75                     break;
    76                 }
    77                 for(int j = 1;j < k;j++){
    78                     if(S[i-j] != S[i+j]){
    79                         flag = 0;
    80                     }
    81                 }
    82             }
    83             if(flag)    puts("DIES");
    84             else        puts("LIVES");
    85         }
    86     }
    87     return 0;
    88 }
    View Code
     1 // CERC 2012
     2 // Problem B: Who wants to live forever?
     3 // O(n) solution
     4 // Author: Arkadiusz Pawlik
     5 
     6 #include <iostream>
     7 #include <string>
     8 #include <algorithm>
     9 using namespace std;
    10 
    11 bool die(string s) {
    12     s += "0";
    13     int n = s.size();
    14     int l = ((n ^ (n-1)) + 1) / 2;
    15     int cnt = n / l;
    16     cout<<"n="<<n<<" l="<<l<<endl;
    17     cout<<"cnt="<<cnt<<endl;
    18     for (int i = 1; i < cnt; ++i) {
    19         for (int k = 0; k < l-1; ++k) {
    20             if (s[i*l+k] != s[i*l-2-k]) return false;
    21         }
    22         cout<<"caca:"<<s[i*l-1]<<endl;
    23         if (s[i*l-1] != '0') return false;
    24     }
    25     return true;
    26 }
    27 /*
    28 string ft(string s) {
    29     for (int i = 0; i < s.size(); ++i) {
    30         if (i % 3 == 2) continue;
    31         s[i] = (s[i] == '1') ? '0' : '1';
    32     }
    33     return s;
    34 }
    35 */
    36 int main() {
    37     int n;
    38     cin >> n;
    39     while(n--) {
    40         string s;
    41         cin >> s;
    42         if (die(s)) cout << "DIES" << endl;
    43         else cout << "LIVES" << endl;
    44     }
    45 }
    View Code
  • 相关阅读:
    Linux查看系统信息
    pgrep 和 pkill 使用小记
    linux下json库的编译及例程
    Epoll 实例
    gcc中的内嵌汇编语言
    BZOJ 1053: [HAOI2007]反素数ant
    2018.7.15模拟赛
    BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
    BZOJ 4241: 历史研究
    LUOGU P2365 任务安排
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3350480.html
Copyright © 2011-2022 走看看