题目描述
锤锤和柯西在玩火柴棒游戏,他们用火柴棒拼成不同的数字。规则如下:
这是火柴所形成10个数字的方式,每个数字所需的火柴数量不一样。现在给两人每人发N根火柴棒。锤锤要用所有火柴棒摆出其所能摆出最小的数,而柯西则需要用所有火柴棒摆出其所能摆出的最大的数。当然,前导 0 或者摆出不规则的数字什么的都算是作弊。现在他们俩都想尽快知道答案,于是请你帮忙。
输入格式
从文件 match.in 中读取数据。
输入包括若干组数据。第一行为一个数字 T,表示锤锤和柯西会进行 T 次游戏。
接下来T行,每行一个正整数 N,表示火柴的数量。
输出格式
输出到文件 match.out 中。
T 行,每组数据包括一行,分别为锤锤所能摆出的最优值以及柯西所能摆出的最优值。
输入输出样例
输入样例1:
1
2
画写样例1:
1 1
说明
【数据范围】
对于 K%的数据:N<=K (K=10,20,...,100)
对于 100%的数据:2<=N<=100,0<T<100
【耗时限制】1000ms 【内存限制】256MB
这一题,上来第一想法就是dfs,但是我可以明确的告诉你们,dfs过不了一点儿
那既然dfs过不了,就得想其他方法吧,总不能不写
再仔细瞅瞅,可以发现一个求最大,一个求最小
好像可以用贪心
那既然是贪心,我们就得规划贪心策略
我们先来看最大的
由于我们知道,两个数中,位数越大的,数值越大,那就明确了一件事情:位数要尽量的
多,也就是每一个数字占的小棍数尽量少,再回过头来看一下在0~9中哪一个最少,很明显,是1,
1只需要两根棍子;所以,我们很容易得到一个结论:
如果总棍数是一个偶数,那么就可以安排上n除以2个1,
如果是奇数呢,就安排上0~9中棍棒数次小的且为奇数的数字,也就是7,需要3根棍子,我们把他安排在第一位
string maxn(int n){
string ans="";
if(n%2==1) ans+='7',n-=3;
for(int i=2;i<=n;i+=2){
ans+='1';
}
return ans;
}
最大的解决了,来看一下最小的
最小的首先位数尽量小,8用的棍棒数最多,有7根,我们先安排8上
如果mod 7余0,不用判断,直接return
如果mod 7余1,把第一个8换下来,换成“10”
如果mod 7余2,不用换,直接在前面加1
如果mod 7余3,就需要再次分类讨论:
当棍棒数为10是,别多想,直接把ans改成“22”
否则,把前两个8改成“200”
如果mod 7余4 把第1个8换成“20”;
如果mod 7余5 不用换,直接加“2“;
如果mod 7余6,就加一个6
下面的是片段代码,完整代码在最后
string minn(int n){
string ans="",w="00174208";
if(n<=7){
ans+=w[n];
return ans;
}
int c=n/7,m=n%7;
for(int i=1;i<=c;i++) ans+="8";
if(m==0) return ans;
if(m==1){
ans[0]='0';
ans="1"+ans;
}
else if(m==2){
ans="1"+ans;
}
else if(m==4){
ans[0]='0';
ans="2"+ans;
}
else if(m==5){
ans="2"+ans;
}
else if(m==3){
if(ans.size()==1) ans="22";
else{
ans[0]=ans[1]='0';
ans="2"+ans;
}
}
else{
ans="6"+ans;
}
return ans;
}
这个是完整代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <string>
using namespace std;
int T;
string maxn(int n){
string ans="";
if(n%2==1) ans+='7',n-=3;
for(int i=2;i<=n;i+=2){
ans+='1';
}
return ans;
}
string minn(int n){
string ans="",w="00174208";
if(n<=7){
ans+=w[n];
return ans;
}
int c=n/7,m=n%7;
for(int i=1;i<=c;i++) ans+="8";
if(m==0) return ans;
if(m==1){
ans[0]='0';
ans="1"+ans;
}
else if(m==2){
ans="1"+ans;
}
else if(m==4){
ans[0]='0';
ans="2"+ans;
}
else if(m==5){
ans="2"+ans;
}
else if(m==3){
if(ans.size()==1) ans="22";
else{
ans[0]=ans[1]='0';
ans="2"+ans;
}
}
else{
ans="6"+ans;
}
return ans;
}
int main(){
scanf("%d",&T);
while(T--){
int x;
scanf("%d",&x);
cout<<minn(x)<<" "<<maxn(x)<<endl;
}
return 0;
}