2020寒假【gmoj2091】【火柴】

题目描述

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

输入

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

输出

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

样例输入

3
1 3
3 512
3 079

样例输出

5
977
997

Hint

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

分析

这题因为n是100000,所以我用了字符串去输入。

  1. 可以建一个数组,存0~9的数字所对应的火柴数。
  2. 输入的时候用sum把这整个数字的火柴总数加一下(把火柴打乱,然后集中在一起)
    然后我发现一个关键点:一个数位至少用两根火柴(1),最多用7根火柴(8)。所以可以设k是剩下的数位总数,sum是还有的火柴总数,p是要放的数。
    怎样判断放p是否合法呢——二次判断。就是放之前合法,放了之后也要合法。怎样算是合法呢?根据关键点可知sum>=2*k&&sum<=7*k就是合法的。知道了这个条件,只需在两次判断之间逆序(9~0)枚举p就可以啦!

上代码!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
string a;
int b[11]={6,2,5,5,4,5,6,3,7,6,0};
long long n,t,sum,ans;
int main()
{
    freopen("match.in","r",stdin);
	freopen("match.out","w",stdout);
	cin>>t;
	for(int i=1;i<=t;i++)//t=1~10
	{
		sum=0;
		cin>>n;
		long long k=n;
		for(int j=1;j<=n;j++)
		{
			cin>>a[i];
			sum=sum+b[a[i]-48];
		}
		while(k>0)
		{
			if(sum>=2*k&&sum<=7*k)
			{
				for(int p=9;p>=0;p--)
				{
					if(sum-b[p]>=2*(k-1)&&sum-b[p]<=7*(k-1))
					{
						sum-=b[p];
						k--;
						cout<<p;
						break;
					}
				}
			}
		}
		cout<<endl; 
	}
	fclose(stdin);
	fclose(stdout); 
    return 0;
}
(*╹▽╹*)//这个表情不仅好看,还能让抄程序的人CE!

发布了63 篇原创文章 · 获赞 61 · 访问量 5473

猜你喜欢

转载自blog.csdn.net/dglyr/article/details/104197100
今日推荐