USACO3.1 Contact(contact)

        因为1<=a<=b<=12,所以可以将输入的字符全部存进str,然后for i:a~b,依次检测str中长度为i的字符串出现的次数,存进map<string,int> map1,然后将map1的key和value翻转,存进multimap<int,string> map2,然后for i:1~n,每次取出第i大的key值对应的value,可以存进set<string>中输出。感觉复杂度蛮高,但是最后一个测试里仅仅0.184s,出乎意料啊。另外程序写的极为难看,恶心到我自己了。。。

        最近在搞数模培训,上午培训,下午晚上自由活动,可是一有时间就想玩,不想玩了吧就想写个程序,数模啊数模,我可不想这么热的天是在这混日子啊。。。

/*
ID:jzzlee1
PROB:contact
LANG:C++
*/
//#include<iostream>
#include<fstream>
#include<map>
#include<set>
#include<string>
#include<cstring>
using namespace std;
ifstream cin("contact.in");
ofstream cout("contact.out");
string str,s;
map<string,int> map1;
multimap<int,string> map2;
map<string,int>::iterator iter;
multimap<int,string>::reverse_iterator p,q;
class rule:greater<string>  
{  
public:  
    bool    operator () (string b1,string b2) const
	{  
        if(b1.size()>b2.size())
			return 0;
		else if(b1.size()<b2.size())
			return 1;
		else
			return b1<b2;
    }  
};
int main()
{
	int a,b,n;
	cin>>a>>b>>n;
	getchar();
	while(getline(cin,s))
	str+=s;
	int i,j;
	if(b>str.size())
		b=str.size();
	if(n>str.size())
		n=str.size();
	for(i=a;i<=b;i++)
	{
		for(j=0;j+i<=str.size();j++)
		{
			s.assign(str,j,i);
			++map1[s];
		}
	}
	for(iter=map1.begin();iter!=map1.end();iter++)
		map2.insert(make_pair(iter->second,iter->first));
	p=q=map2.rbegin();
	for(i=0;i!=n;i++)
	{
		j=1;
		set<string,rule> iset;
		while(p!=map2.rend()&&p->first==q->first)
		{
			iset.insert(p->second);
			p++;
		}
		set<string,rule>::reverse_iterator iser=iset.rbegin();
		if(iset.empty())
			break;
		cout<<q->first<<endl;
		set<string,rule>::iterator iseter;
		for(iseter=iset.begin();iseter!=iset.end();iseter++)
		{
			if(j%6)
			{
				if(j%6!=1)
					cout<<" ";
				cout<<*iseter;
			}
			else
				cout<<" "<<*iseter<<endl;
			j++;
		}
		q=p;
		if((j-1)%6)
			cout<<endl;
	}
	return 0;
}

转载于:https://my.oschina.net/u/347565/blog/66519

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值