zoukankan      html  css  js  c++  java
  • 题解 CF1109B Sasha and One More Name

    先考虑Impossible的情况。

    显然如果所有字符全一样那肯定无解。

    还有一种情况就是 (n) 为奇数且除了中间的一个字符其余全部相等,也无解。

    理由很简单,剩下的字符全相等,由于新串是回文的,所以和原来的串一定是同一个串。

    下面我们分奇偶性来讨论。

    • (n) 为奇数

    这种情况下,答案不大于 (2) ,因为除了中间的旁边的字符不全相等,所以一定有中间的一段,他的两边不是回文串,直接切两下就行了。

    同时,答案也不可能小于 (2) ,因为如果一刀就行的话,由于新串回文,且长度为奇数,所以手动模拟一下就能看出,这样一定所有字符都相等才能让新串和原串全都回文,而这时答案为Impossible,不符合题意。

    所以当 (n) 为奇数时,答案为 (2)

    • (n) 为偶数

    这时稍微麻烦一点,分两种情况。

    我们取串的前一半,由于是回文长度为偶数的串,所以后一半一样的不用管就可以了。

    1. 取出的这个串不是回文串,这时直接一刀把原串从中间分成两段即可,答案为 (1)
    2. 取出的串是回文串,这样我们可以把整个原串分成两半,因为这一半回文,所以求出当串长为 (frac{n}{2}) 时的答案。如果是 (2) 就对称的切一刀,原串答案仍为 (2) 。如果是 (1) 就还在那个位置切,原串答案仍为 (1) 。所以新串的答案即为原串的答案,递归处理即可。

    时间复杂度 (O(nlog n))

    代码

    #include<bits/stdc++.h>
    #define re register
    #define N 1001001
    #define MAX 2001
    #define inf 1e18
    using namespace std;
    typedef long long ll;
    typedef double db;
    inline void read(re ll &ret)
    {
        ret=0;re ll pd=0;re char c=getchar();
        while(!isdigit(c)){pd|=c=='-';c=getchar();}
        while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();}
        ret=pd?-ret:ret;
        return;
    }
    ll t,n;
    char s[N];
    signed main()
    {
        t=1;
        while(t--)
        {
            scanf("%s",s+1);
            n=strlen(s+1);
            re bool flag=true;
            for(re int i=2;i<=(n>>1);i++)
                flag&=(s[i]==s[i-1]);
            if(flag)
            {
                puts("Impossible");
                continue;
            }
    start:
            flag=true;
            for(re int i=1;(i<<1)<=n;i++)
            {
                if(s[(n>>1)-i+1]!=s[i])
                    flag=false;
            }
            if(!flag&&(n&1))
            {
                puts("2");
                continue;
            }
            else if(!flag&&!(n&1))
            {
                puts("1");
                continue;
            }
            else if(flag&&(n&1))
            {
                puts("2");
                continue;
            }
            else if(flag&&!(n&1))
            {
                n>>=1;
                goto start;//即为前文所说的递归,goto简化代码
            }
     
        }
    	exit(0);
    }
    
  • 相关阅读:
    软件工程第1次阅读作业
    软件工程第0次作业
    OO第四次博客
    OO第三次总结
    OO第二次总结
    OO第一次总结
    提问回顾与个人总结
    结对项目:最长单词链
    第一次阅读作业
    第四次博客
  • 原文地址:https://www.cnblogs.com/CelticBlog/p/13832386.html
Copyright © 2011-2022 走看看