1058 题意:
整体思想是利用已经知道的序列中的元素根据规则去生成新的元素, 如x * 2, x * 3, x * 5, x * 7.
假设使用数组a[MAX]进行存储这一序列的所有元素, 首先使a[0] = 1, 表示第一个元素是1, 然后利用4个指针(不是内存指针,呵呵), i2 = i3 = i5 = i7 = 0. 每次我们比较 a[i2] * 2, a[i3] * 3, a[i5] * 5, a[i7] * 7 这四个元素的大小, 把最小的放到序列中, 并把对应的指针+1, 直到生成需要的个数.
#include<stdio.h>
#include<string.h>
#define min(e,f) (e)>(f)?(f):(e)
int dp[6000] = { 0, 1 },i2 = 1, i3 = 1, i5 = 1, i7 = 1, cnt = 1, N;
char lst[5][5] = { "th", "st", "nd", "rd" };
int getUp () {
int t = min ( min ( 2*dp[i2], 3*dp[i3] ),
min ( 5*dp[i5], 7*dp[i7] ) );
if ( t == 2*dp[i2] ) ++ i2;
if ( t == 3*dp[i3] ) ++ i3;
if ( t == 5*dp[i5] ) ++ i5;
if ( t == 7*dp[i7] ) ++ i7;
return t;
}
void init () {
for ( int i = 2; i <= 5842; ++ i ) {
dp[i] = getUp ();
}
}
char * getLst ( int n ) {
if ( n % 100 != 11 && n % 10 == 1 ) return lst[1];
else if ( n % 100 != 12 && n % 10 == 2 ) return lst[2];
else if ( n % 100 != 13 && n % 10 == 3 ) return lst[3];
else return lst[0];
}
int main ()
{
init();
while ( scanf("%d",&N)!=EOF &&N)
{
printf ( "The %d", N );
printf ( "%s", getLst ( N ) );
printf ( " humble number is %d.\n", dp[N] );
}
return 0;
}
hdu3199 类似的思想,那个数的范围倒是够吓人的
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
__int64 dp[10000];
__int64 p[4],a,b,c,n;
int main()
{
while(scanf("%d %d %d %d",&p[1],&p[2],&p[3],&n)==4)
{
a=b=c=0;
dp[0]=1;
for(int i=1;i<=n;i++)
{
__int64 t=min(min(p[1]*dp[a],p[2]*dp[b]),p[3]*dp[c]);
if(t==p[1]*dp[a]) a++;
if(t==p[2]*dp[b]) b++;
if(t==p[3]*dp[c]) c++;
dp[i]=t;
}
printf("%I64d\n",dp[n]);
}
return 0;
}