作为谔谔Round div.2的第一题,这题还是比较良心的。
肥肠适合用来练习基础的码字思维能力。(然而这个lj还是交满了几页提交记录,让我们一起来嘲讽他吧!)
(话说语文王子看见这题有什么感受)
(语文王子:谔我谔)
扯远了,我继续来讲这题的思路:(大佬们可以跳过这段)
-
首先,从整个字符串中找出最多的字符 ;
-
接着将它复制 个,放在字符串的后面;
-
如果这句话还是很逊,那么就再找出最多的字符 ,否则输出;
-
复制;
-
判断&查找;
...
可以算出,这种方法的复杂度大约是 ,明显过不了 的这种大数据(虽然不知道有没有)。
如果是这样,我们就要优化它。
仔细观察题面,可以看出,我们其实只用找一次数量最多的字符就可以了。因为在每次操作之后只有之前最多的字符变多了,所以下次操作时最多的字符跟这次找到的字符是同一个。这样就可以把时间压进 以内:(大佬们还是可以跳过这段)
-
首先,从整个字符串中找出最多的字符 ;
-
接着将它复制 个,放在字符串的后面,并执行
x*=2;(因为又新增了 个这种字符); -
如果这句话还是很逊,那么就再复制 个,并执行
x*=2,否则输出; -
复制 or 输出
-
复制 or 输出
...
这就是本题的要点了。当然还有一些需要注意的地方:(大佬们仍然可以跳过这段)
- 数据很大,需要int128.
- 字符串 中不全是小写字母.
- 在本地运行时要用
\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
}
杜绝抄题解,共创美好洛谷
(一道橙题应该没人抄吧)