Problem 1068 An Interesting Set.
题意
- 正数集合S满足:
①所有位上数的总和等于他们的乘积
②如果s在S中,那么2s也在S中 - 输入:
n,表示n个测试数据
跟着n行k - 输出:
集合S中第K小的数
思路
两个数组,一个flag[1000000]用于标记数字是否属于S,另一个ans[500]按从小到大顺序存放S的元素,len表示ans数组的长度
对len初始值设1,数字1进ans
对当前k:
①k<=len,直接输出ans[k-1]
②k>len,从ans[len-1]+1开始遍历,设当前遍历数字x:
- flag[x]是否为0?
是:按规则①计算,和等于积吗?不等于,x不符合S的要求,continue
flag[x]为1,或计算后符合S要求:x放入ans中,len++,同时将flag[2x]置1 - len==k结束遍历,输出ans[k-1]
笔记
- 从ans[len-1]+1开始遍历
- 一开始想直接把1-9都存进去,可是这样子做会导致4*4=16不符合规则,所以还是老老实实从1开始一个个算,不差这一点
代码
#include<cstdio>
int flag[1000000]={0}, ans[500] = {1};
int len = 1;
int main(){
int n, k;
int ji, he, temp;
scanf("%d", &n);
while(n--){
scanf("%d", &k);
if(k<=len){
printf("%d\n", ans[k-1]);
}else{
for(int x=ans[len-1]+1; k>len; x++){
if(flag[x]==0){
ji = 1;
he = 0;
temp = x;
while(temp){
ji = ji*(temp%10);
he = he + (temp%10);
temp = temp/10;
}
if(ji!=he)
continue;
}
ans[len++] = x;
flag[2*x] = 1;
}
printf("%d\n", ans[k-1]);
}
}
return 0;
}