Humble Numbers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 28999 Accepted Submission(s): 12761
Write a program to find and print the nth element in this sequence
题意:找出所有只含因数2、3、5、7的数字并输出
之前比赛的时候队友暴力打表,提示代码超限(当时真是没想到23333)
后来用的vector过的,不过比较麻烦,需要去重和排序。
一直对这题耿耿于怀,因为蓝桥杯有一道类似的题目我也被卡住了,很难受,结果拖到现在才来补题
后来发现这题很少有详细的题解,所以我尝试写一发
首先我们知道至少有5个数符合条件,分别是1,2,3,5,7.
那么之后我们会想到利用2,3,5,7这几个因数不断利用已经得出的结果相乘
比如对1,2,3,5,7分别乘以2得到2,4,6,10,14
那么现在我们有1,2,3,4,5,6,7,10,14
之后对于现有的数组都乘以3
会得到1,2,3,4,5,6,7,9,10,14,15(这里15之后的数我就不写了,实在太累了233)
乘以5,会得到1,2,3,4,5,6,7,9,10,14,15 (同理15之后的数字在以后省略)
乘以7,仍是1,2,3,4,5,6,7,9,10,14,15
之后再乘以2,这时会有1,2,3,4,5,6,7,9,10,12,14,15
注意一下,这个时候前15个数据才会完整体现出来!!!
普通因数相乘比较麻烦,所以dp处理
pos是记载这个因数处理到第几个数字了(这个数字指的是最后的结果数组)
因为我们会让所有的数字都乘以2,3,5,7,所以pos都从1开始,并随之不断更新
注意pos更新的时候会自动过滤掉重复的数字,比如2*3=6和3*2=6
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long a[6000];
int main()
{
a[1]=1;
int pos1=1,pos2=1,pos3=1,pos4=1;
long long n1,n2,n3,n4;
for(int i=2; i<=5842; i++)
{
a[i]=min(min(n1=a[pos1]*2,n2=a[pos2]*3),
min(n3=a[pos3]*5,n4=a[pos4]*7)); ///找到当前最小,因为只有这样才能确保最后的结果数组是有序的
if(a[i]==n1) /// 这里千万不要加else,否则就会出现重复的数字
pos1++;
if(a[i]==n2)
pos2++;
if(a[i]==n3)
pos3++;
if(a[i]==n4)
pos4++;
}
int num;
while(~scanf("%d",&num)&&num) ///输出巨坑
{
printf("The %d",num);
if (num % 100 != 11 && num % 10 == 1)
{
printf("st");
}
else if (num % 100 != 12 && num % 10 == 2)
{
printf("nd");
}
else if (num % 100 != 13 && num % 10 == 3)
{
printf("rd");
}
else
{
printf("th");
}
printf(" humble number is %lld.\n",a[num]);
}
}