题目描述
味味最近在玩猜数字的游戏,现在她也希望你来玩一下这个游戏。猜数字游戏的规则是这样的,告诉你一个正整数 n(2<=n<=11),然后味味心中会想一个 n 个数字组成的数字串(数字串最前面若干位可能是 0)。味味会随意排列 n 位数上的数字,这样可能产生 n!个 n位数。(n!=1×2×3×4×5×……×n,n!念作“n 阶乘”). 比如味味想了一个三位数 abc,那么一共会产生六个三位数,分别为 abc,acb,bac,bca,cab,cba然后味味会把这 n!个 n 位数求和得到 S(若某数第一位开始有若干个 0,则求和时这 些 0 舍去。如有数“0123”,则求和时加到 s 中的值是 123),她会告诉你总和 S 减去她心 中想的那个数的值,请你猜出味味心中想的那个数。
输入
输入共包含两行。第一行一个整数 n(含义如前面所述),第二行一个正整数 S,表示 n!个数的总和减去味味心中那个数的值。输出
输出共一行一个数,表示味味心中想的那个n位数(测试数据保证存在唯一解)。如果该数第一位开始有若干个0,则输出时这些0也必须输出。样例输入 Copy
2
90
样例输出 Copy
09
提示
如果味味心中想的是 09,则 S=09+90-09=9+90-9=90,符合要求。对于 20%的数据 n≤3
对于 60%的数据 n≤5
对于 100%的数据 2≤n≤11 ,0≤S≤1018 思路:我们假设这个数的每一位分别是a,x,y,z 那么这个数本身是a*1000+x*100+y*10+z,那么n!种排列方式之和推一下可以化成(1000+100+10+1)*(a+x+y+z)*(n-1)!, 然后枚举里面的和即可
代码
#include<iostream>
#define int long long
#pragma GCC optimize(2)
using namespace std;
int n,s;
signed main()
{
cin>>n>>s;
int k=1;
for(int i=1;i<n;i++)
k=k*10+1;
for(int i=2;i<n;i++)k*=i;
int i=0,t=0,p=-1,q;
while(i!=p)
{
i++;
q=k*i-s;
if(q<=0)continue;
p=0,t=0;
while(q>0)
{
p+=q%10;
t++;
q/=10;
}
}
for(;t<n;t++)putchar('0');
cout<<p*k-s;
return 0;
}