火柴(2020.02.05【NOIP普及组】模拟赛C组)

题目描述
在这里插入图片描述
给定一个N位的数,将火柴棍重新排列后,能得到的最大的数是多少?
注意不能多出或者少一位, 火柴棍要全部用上.

输入

第一行整数T,表示数据组数
接下来T行,每行一个整数N, 然后是N位数,表示原来的数,可能会有前导0,中间用空格隔开。

输出

对于每组数据,输出一行,最大的能得到的数是多少。

样例输入

3
1 3
3 512
3 079

样例输出

5
977
997

数据范围限制

对于20%的数据:1 ≤ n ≤ 10
对于60%的数据:1 ≤ n ≤ 1000
对于100%的数据: 1 ≤ n ≤ 100000,1 ≤T≤ 10

分析:这道题一看就知道用贪心。从高位到低位(保证能得到最大的数),从大到小(保证当前所选数最大)。然而光这样是不行的,因为题目规定将火柴棍重新排列后,不能多出或者少一位。所以我们则每次选数后都要进行判断(用花费火柴数最少的和花费火柴数最多的进行限制)

code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int hzs[10]={6,2,5,5,4,5,6,3,7,6};
int t,n,sum,tt;
char ch;
bool pd(int i,int j)  //因为题目规定不能多出或者少一位,所以每选择一个数就要进行判断,判断剩下的全部用2(因为它所用火柴数最少)或8(同理)是否能装的下 
{
	return i*2<=j&&j<=i*7;
}
int main()
{
	//freopen("match.in","r",stdin);
	//freopen("match.out","w",stdout);
	cin>>t;
	while(t--)
	{
		char x;
		sum=0;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>ch;
			sum+=hzs[ch-'0'];  //加总所用火柴数 
		}
		for(int i=1;i<=n;i++)
		{
			tt=9;  //因为它说重新排列后数要最大,所以要从9开始 
			if(i==n)  //判断是否是最后一位,如果是最后一位,一定是会被刚刚好sum=0,所以只用找所花火柴数等于sun就可以了! 
			{
				while(sum!=hzs[tt])
					--tt;
				cout<<tt; 
				break;
			}
			while(!pd(n-i,sum-hzs[tt]))  //如果不满足条件,就继续往下判断 
				--tt;
			sum-=hzs[tt];
			cout<<tt;
		}
		cout<<endl;  //换行 
	}
	return 0;  //结束
}

谢谢

发布了80 篇原创文章 · 获赞 58 · 访问量 2548

猜你喜欢

转载自blog.csdn.net/bigwinner888/article/details/104201147