Pat(Advanced Level)Practice--1038(Recover the Smallest Number)

Pat1038代码

题目描述:

Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given {32, 321, 3214, 0229, 87}, we can recover many numbers such like 32-321-3214-0229-87 or 0229-32-87-321-3214 with respect to different orders of combinations of these segments, and the smallest number is 0229-321-3214-32-87.

Input Specification:

Each input file contains one test case. Each case gives a positive integer N (<=10000) followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the smallest number in one line. Do not output leading zeros.

Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287

AC代码:

如果一个字符串是另一个字符串的前缀,那么两个字符串的大小要分情况而定

例如:S1=32

            S2=32XXXXX

那么只要比较3232XXXXX

                        32XXXXX32之间的大小即可

两个循环就可以搞定。

解法一,逐个字符进行比较,比较繁琐,但效率很高

解法二,是在解法一的基础上改进的,既然要求两个字符串的大小

那么直接进行相加比较岂不是更快。(这是在解法一快写完时才发现的捷径)


解法一:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

bool cmp(const string &s1,const string &s2)
{
	int i,j;
	for(i=0,j=0;i<s1.size()&&j<s2.size();i++,j++)
	{
		if(s1[i]==s2[j])
			continue;
		else
			break;
	}
	if(i==s1.size())//s1是s2的前缀
	{
		int k,m;
		for(k=0;k<s2.size()&&j<s2.size();k++,j++)
		{
			if(s2[j]==s2[k])
				continue;
			else if(s2[k]<s2[j])
				return true;
			else 
				return false;
		}
		for(m=0;m<s1.size()&&k<s2.size();m++,k++)
		{
			if(s1[m]==s2[k])
				continue;
			else if(s2[k]<s1[m])
				return true;
			else 
				return false;
		}
		return true;
	}
	else if(j==s2.size())//s2是s1的前缀
	{
		int k,m;
		for(k=0;k<s1.size()&&i<s1.size();i++,k++)
		{
			if(s1[k]==s1[i])
				continue;
			else if(s1[i]<s1[k])
				return true;
			else 
				return false;
		}
		for(m=0;m<s2.size()&&k<s1.size();m++,k++)
		{
			if(s2[m]==s1[k])
				continue;
			else if(s2[m]<s1[k])
				return true;
			else
				return false;
		}
		return true;
	}
	else 
	{
		if(s1<s2)
			return true;
		else 
			return false;
	}
}

int main(int argc,char *argv[])
{
	int i,j,n;
	string s;
	vector<string> v;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		cin>>s;
		v.push_back(s);
	}
	sort(v.begin(),v.end(),cmp);
	string ans=v[0];
	for(i=1;i<n;i++)
		ans+=v[i];
	int t=0;
	while(t<ans.size()&&ans[t]=='0')
		t++;
	if(t==ans.size())
		cout<<"0"<<endl;
	else
		cout<<&ans[t]<<endl;

	return 0;
}

解法二:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

bool cmp(const string &s1,const string &s2)
{
	string s3,s4;
	s3=s1+s2;
	s4=s2+s1;
	if(s3<s4)
		return true;
	else 
		return false;
}

int main(int argc,char *argv[])
{
	int i,j,n;
	string s;
	vector<string> v;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		cin>>s;
		v.push_back(s);
	}
	sort(v.begin(),v.end(),cmp);
	string ans=v[0];
	for(i=1;i<n;i++)
		ans+=v[i];
	int t=0;
	while(t<ans.size()&&ans[t]=='0')
		t++;
	if(t==ans.size())
		cout<<"0"<<endl;
	else
		cout<<&ans[t]<<endl;

	return 0;
}

本题核心是贪心算法,关键是排序算法怎么写的问题。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值