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; }