P1854 Children‘s Game

题目分析

我们首先翻译一下题目,玩家会获得n个正整数(n<=50),进行排列组合。例如四个整数123,124,56,90,可以生成4*3*2*1共计24种组合,其中显然最大组合情况为9056124123。

这很容易想到应该将数值最大的数放在权值的高位。所以我们要做的就是给n个正整数排序,排序的规则的从第一位开始比较,从大到小,依次是第二位第三位,如果没有下一位,视为目前最大,排在前面。

一开始我认为本题数据量很小,对于排序规则的实现部分,就可以大胆的随意的去使用蛮力,结果超时。

#include<iostream>
using namespace std;
int getk(int num,int k)
{  
    if (num == 0)  
        return 0;  
    while (num >=k*10)
        num /= 10;   
		if(k==1)  
		return num;
        else
		return num%((k-1)*10);  
} 
int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0)
		return 0;
		int a[n];
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n-i-1;j++)
			{
				for(int k=1;k<=32;)
				{
					if(getk(a[j],k)<getk(a[j+1],k))
					{
					int temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
					break;
				    }
				    if(getk(a[j],k)==getk(a[j+1],k))
						k++;
		    	}
			}
		}
		for(int i=0;i<n;i++)
		{
			cout<<a[i];
		}
		cout<<endl;
    }
    return 0;
}

我回想了一下解题思路,发现确实没想到什么合适的算法来优化,不过在写上面一段排序规则的时候,我想到了字符串比较函数,这两个高度相似,为此我还去搜了一下关于正整数有没有类似字符串的处理函数。

说到这已经恍然大悟了,完全可以将数字当做字符串处理。如下。

#include<iostream>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0)
		return 0;
		string a[n];
		for(int i=0;i<n;i++)
		{
			cin>>a[i];
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n-i-1;j++)
			{
					if(a[j]<a[j+1])
					{
					string temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				    }
			}
		}
		for(int i=0;i<n;i++)
		{
			cout<<a[i];
		}
		cout<<endl;
    }
    return 0;
}

这个时候运行会发现一个致命的问题。我们将如果没有下一位,视为目前最大,但是对于“a”,是小于“ad”的,这个例子中,第一个字符串没有第2位字符相当于null,null的ascll值等于0,而‘d’的ascll的值为100,所以后者大于前者。而我们需要将“9”视为排在“90”前面。

那么改为字符串处理的问题出现了,我们该怎么解决呢?这里我采用了参考的一个思路。我们如果使用sort函数对字符串数组a排序,cmp的代码是比较a[i]和a[j]的大小,这里我们不妨将cmp函数改为a[i]+a[j]和a[j]和a[i]比较大小,这样就有效的解决了前面那个问题同时符合我们的逻辑初衷。

这里解释一下为什么要这么写cmp,因为我们想求的就是正整数组合之后的结果最大,所以说这个解法符合我们的逻辑初衷。对于字符串string,使用+就可以连接成为一个字符串,从而比较“990”和“909”哪一个更大。

ac代码

#include<iostream>
#include<algorithm>
using namespace std;
int cmp(string a,string b)
{
return a+b>b+a;
}
int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0)
		return 0;
		string a[n];
		for(int i=0;i<n;i++)
			cin>>a[i];
		sort(a,a+n,cmp);
		for(int i=0;i<n;i++)
			cout<<a[i];
		cout<<endl;
    }
    return 0;
}

  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值