时间: 1000ms / 空间: 655360KiB / Java类名: Main
背景
冬令营入学测试题
描述
题目描述
小D是一名魔法师,它最喜欢干的事就是对批判记者了。
这次记者招待会上,记者对于小D的数学很好奇。于是小D找了个方法把记者批判了一番。
它对记者抛出了这么一个问题:我有n点能量,写下数字i(1<=i<=9)需要花费a{i}点能量,我用这n点能量最多能写出什么数来?(当然可以不用光n点能量,具体看样例)
记者们一脸懵逼,于是来求助于你。
输入格式
一行10个数,表示n,a1,a2,a3,…,a9。
输出格式
一个数表示答案。
备注
输入样例1
10 2 2 1 2 2 2 2 2 2
输出样例1
3333333333
输入样例2
10 4 11 11 11 11 11 11 11 10
输出样例2
11
数据范围
对于30%的数据n,ai<=10。
对于60%的数据n,ai<=100。
对于100% 的数据1<=n,ai<=1000000,n>=min{ai}。
数的大小首先看位数,其次看最高位,然后是次高位……
位数为总能量/花费能量最小的数
设花费能量最小的数为a,花费能量s,答案至少为s/a位s。如果有多个花费能量最小,取数最大的那个
然后用总能量%s,得出还剩下多少能量值。即还有多少能量可以在让答案位数不变的前提下,变得更大。
然后从9开始倒着枚举,如果剩下的能量足够更新一个,那就让最高位更新,其次是次高位,以此类推。
枚举结束条件:1、枚举到的数<=a 2、当前步骤剩下的能量不能更新任何一个数
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,minn=0x7fffffff,d;
int ans[];
struct node
{
int w;//写下p需要w点能量
int p;
}a[];
bool cmp(node x,node y)//从9——1排序
{
return x.p>y.p;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=;i++)
{
scanf("%d",&a[i].w);
a[i].p=i;
if(a[i].w<=minn)//minn当前耗费最小的能量
{
minn=a[i].w;
d=a[i].p;//耗费能量minn写下的最大的数
}
}
int t=n%minn,tt=n/minn;//tt:ans的位数,t:写下tt位d后剩下的能量
sort(a+,a+,cmp);//从9——1排序
//sort(a+1,a+10,greater<int>());
int k=;//当前可更新的最高位
for(int i=;i<=tt;i++) ans[i]=d;//写下tt位d
while(t)
{
bool ok=false;//ok起的作用:当当前步骤剩下的能量不能更新任何一个数时,退出
for(int i=;i<=;i++)//将此处循环改成从9——1,把结构体改成数组a[i]=j代表写下i用j点能量,可以省去前面sort排序
if(a[i].p<=d) break;//a[i].p从大到小排序,如果当前的p小于d,后面的一定小于d,更新会使ans更小。如果p等于d。没有更新必要
else if(a[i].w-minn<=t)//能量可以将d更新成a[i].p
{
ans[k++]=a[i].p;//先更新,k再++
t=t-(a[i].w-minn);
ok=;
break;
}
if(ok) continue;
else break;
}
for(int i=;i<=tt;i++) cout<<ans[i];
}