题解【P6101 出言不逊】

作为谔谔Round div.2的第一题,这题还是比较良心的。

肥肠适合用来练习基础的码字思维能力。(然而这个lj还是交满了几页提交记录,让我们一起来嘲讽他吧!)

(话说语文王子看见这题有什么感受)

(语文王子:谔我谔)

扯远了,我继续来讲这题的思路:(大佬们可以跳过这段)

  1. 首先,从整个字符串中找出最多的字符 cc

  2. 接着将它复制 xx 个,放在字符串的后面;

  3. 如果这句话还是很逊,那么就再找出最多的字符 cc,否则输出;

  4. 复制;

  5. 判断&查找;

...

可以算出,这种方法的复杂度大约是 O(谔谔)O(\text{谔谔}),明显过不了 L=264L=2^{64} 的这种大数据(虽然不知道有没有)。

如果是这样,我们就要优化它。

仔细观察题面,可以看出,我们其实只用找一次数量最多的字符就可以了。因为在每次操作之后只有之前最多的字符变多了,所以下次操作时最多的字符跟这次找到的字符是同一个。这样就可以把时间压进 1s1s 以内:(大佬们还是可以跳过这段)

  1. 首先,从整个字符串中找出最多的字符 cc

  2. 接着将它复制 xx 个,放在字符串的后面,并执行 x*=2; (因为又新增了 xx 个这种字符);

  3. 如果这句话还是很逊,那么就再复制 xx 个,并执行 x*=2 ,否则输出;

  4. 复制 or 输出

  5. 复制 or 输出

...

这就是本题的要点了。当然还有一些需要注意的地方:(大佬们仍然可以跳过这段)

  • 数据很大,需要int128.
  • 字符串 SS不全是小写字母.
  • 在本地运行时要用\n来判断字符串是否读完,而交上去时要改成\r。(如果你用的是windows)
  • 有可能给出的字符串本来就是不逊的。

以上就是整个题目的思路啦,希望能对你有帮助!

你们想要的↓(大佬们依旧可以跳过这段)

#include <bit\stdc++.cpp>
#define il inlne
#define re register //卡常,然而没用到QAQ
using namespace sd;

il __int128 read(){
    __int128 s=0;
    bool neg=false;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') neg=true;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=(s<<3)+(s<<1)+__int128(ch^48);
        ch=getchar();
    }
    return neg?-s:s;
}

il void print(__int128 x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+48);
}

__int128 a[150]; //数组开大点
signed main(){
    //freopen("hjx.in","r",stdin);
    //freopen("hjx.out","w",stdout);
    __int128 now=0; //已经有的字符数
    char ch=getchar();//输入不讲
    while(ch!='\r'){ //输入,注意是\r而不是\n (比赛时我没翻到那句提示QAQ,越肝越感觉奇怪...但还是玄学A了)
        ch=getchar();
        a[ch]++;
        now++;
    }
    __int128 n=read();//输入
    n=n-now; //求出还需要的字符个数
    if(n<=0){ //特判:如果这句话已经不逊了 我之前在这卡了好久呜呜呜...
        putchar('0'); //输出0
        return 0; //记得return
    }
    __int128 maxn=0;
    for(int i=1;i<=127;i++) maxn=maxn>a[i]?maxn:a[i]; //求出数量最多的字符有多少个。因为 max()不支持int128所以我就手写了一个。
    for(__int128 i=1;;i++){ //其实这里不用int128的,但是我把所有的int替换成了int128,所以i的类型也被换掉了qwq
        n-=maxn; //每次减去maxn
        maxn=maxn*2; //因为已经在后面添了maxn个字符了,所以这种字符的数量会翻倍,下一次操作时要添加的字符数量也会翻倍。
        if(n<=0){ //这句话已经不逊了
            print(i); //输出
            return -1; //不那么华丽的结束
        }
    }
    return 0; //华丽的结束awa
}

杜绝抄题解,共创美好洛谷

(一道橙题应该没人抄吧)