您的位置:首页 > 编程语言 > C语言/C++

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

2014-03-11 20:22 651 查看

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;
}


本题核心是贪心算法,关键是排序算法怎么写的问题。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息