首页 > 其他 > 详细

题解 P6101【出言不逊】

时间:2020-05-09 21:21:56      阅读:94      评论:0      收藏:0      [点我收藏+]

我知道了,但你出言不逊是!

这题嘛\(\ldots\ldots\) 比赛时瞎打一通,结果真过了。

下面是正题:首先,来审题。注意只是出现,并不一定是连续出现,我在比赛一开始时没仔细看,在加上样例也有误导性,就将简单问题复杂化了。每次操作后,可增加的字符数量就会翻倍。

弄清楚题目后,就会发现其实这题就是一个再简单不过的贪心。稍微进行简单的分析,也就可以知道:在读入字符串的时候,找出出现次数最多的字符,然后一直对它出言不逊进行如题所说的操作,所需的步数就是最小的了。

cin>>s>>l;
for(register int i=0;i<s.length();++i)
{
	++a[s[i]-‘0‘];         //相当于用字符作下标。 
	if(a[s[i]-‘0‘]>hsy)         //当此字符数量更多时,就更新答案。 
	{
		hsy=a[s[i]-‘0‘];
	}
}

至于操作过程,先用一个变量存储 \(|S|\)\(L\) 的差,然后进入一个死循环,在循环内判断。如果所增加的字符数大于等于 此变量,就输出,然后跳出循环;否则,将此变量减去所增加的字符,然后将每次字符增加的量乘上 \(2\),继续循环\(\ldots\ldots\)总有一天会达到的。

l-=s.length();   //求出梦想和现实的差距。 
while(1)
{
	if(hsy>=l)      //如果可以出言不逊了,就输出。 
	{
		cout<<ans<<endl;
		return 0;
	}
	l-=hsy;    //否则,差距减去增加的部分。 
	hsy*=2;    //每次增加的数量要乘以 2。 
	++ans;
}

这样做的好处就是可以避免在 \(n\leq2^{64}\) 这种毒瘤数据下会爆 usigned long long 的可能,毕竟打一个高精度是很烦的。

但它的坏处就是,在 \(|S|\geq L\) 时,就会出错,所以要进行一次特判。

if(s.length()>=l)     //此时不用变化。 
{
	cout<<0;       
	return 0;
}

交上去,就能愉快地 AC 了。


泥萌最喜欢的完整 AC 代码:

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
string s;
ull l,a[101],hsy,ans=1;
int main()
{
	cin>>s>>l;
	if(s.length()>=l)     
	{
		cout<<0;       
		return 0;
	}
	for(register int i=0;i<s.length();++i)
	{
		++a[s[i]-‘0‘];        
		if(a[s[i]-‘0‘]>hsy)      
		{
			hsy=a[s[i]-‘0‘];
		}
	}
	l-=s.length();  
	while(1)
	{
		if(hsy>=l)      
		{
			cout<<ans<<endl;
			return 0;
		}
		l-=hsy;   
		hsy*=2;    
		++ans;
	}
	return 0;	
}

我知道,肯定有很多大佬的程序能吊打我,但是体谅一下一个小蒟蒻吧。

题解 P6101【出言不逊】

原文:https://www.cnblogs.com/win10crz/p/12859662.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!