B - Humble Numbers
[by_041]
题目链接_shnu_OJ
题目理解
一看题就知道是典型的dp了,不难想到从之前有的humble number推出新的humble number,进一步,为了保持有序性,我们要更新出最小的humble number,因为是从前往后更新,我们叫这样的数据结构栈,并且用int sta_f=1, sta_v[6001]={-1,1};
来初始化储存栈的长度sta_f和第i个humble number——sta_v[i]、
那么我们设置int the_2=1,the_3=1,the_5=1,the_7=1;
分别表示可被2、3、5、7整除的第几个humble number,在顺序更新中记录下每个基数更新到的个数(也就是第the_n个可能被n更新出来的数,其中n是2、3、5、7中的某个数),下一次更新出来的数就是 m i n { n ∗ s t a _ v [ t h e _ n ] } , n ∈ { 2 , 3 , 5 , 7 } min\{n*sta\_v[the\_n]\},n\in\{2,3,5,7\} m i n {
n ∗ s t a _ v [ t h e _ n ] } , n ∈ {
2 , 3 , 5 , 7 } ,即可得到核心代码如下:
while ( sta_f< 6000 )
{
sta_v[ ++ sta_f] = minn ( minn ( 2 * sta_v[ the_2] , 3 * sta_v[ the_3] ) , minn ( 5 * sta_v[ the_5] , 7 * sta_v[ the_7] ) ) ;
the_2+ = ! ( sta_v[ sta_f] % 2 ) ;
the_3+ = ! ( sta_v[ sta_f] % 3 ) ;
the_5+ = ! ( sta_v[ sta_f] % 5 ) ;
the_7+ = ! ( sta_v[ sta_f] % 7 ) ;
}
这题还有一个坑点就是序数词后缀(比如末两位是1113的用th,其余的末尾是1 3的不是th)这一点对于输入的ask_n可以进行以下操作来输出其序数词:
if ( ask_n% 10 <= 3 )
{
if ( ask_n% 100 > 10 && ask_n% 100 < 20 )
{
putchar ( 't' ) ; putchar ( 'h' ) ;
}
else
{
switch ( ask_n% 10 )
{
case 0 :
putchar ( 't' ) ; putchar ( 'h' ) ;
break ;
case 1 :
putchar ( 's' ) ; putchar ( 't' ) ;
break ;
case 2 :
putchar ( 'n' ) ; putchar ( 'd' ) ;
break ;
case 3 :
putchar ( 'r' ) ; putchar ( 'd' ) ;
break ;
}
}
}
else
{
putchar ( 't' ) ; putchar ( 'h' ) ;
}
遂得到AC码(打这个的时候个人有点恶趣味,勿介ha):
#include <cstdio>
#include <bitset>
using namespace std;
void swp ( int & a, int & b)
{
a^ = b; b^ = a; a^ = b; return ; }
int maxx ( int a, int b)
{
return a> b? a: b; }
int minn ( int a, int b)
{
return a< b? a: b; }
int input ( )
{
char ch= getchar ( ) ;
while ( ch< '0' || ch> '9' )
ch= getchar ( ) ;
int a= ch- '0' ;
while ( ( ch= getchar ( ) ) >= '0' && ch<= '9' )
a= ( a<< 3 ) + ( a<< 1 ) + ch- '0' ;
return a;
}
void output ( int a)
{
if ( a> 9 )
output ( a/ 10 ) ;
putchar ( a% 10 + '0' ) ;
return ;
}
int ask_n, v_in, the_2= 1 , the_3= 1 , the_5= 1 , the_7= 1 , sta_f= 1 , sta_v[ 6001 ] = {
- 1 , 1 } ;
int main ( )
{
while ( sta_f< 6000 )
{
sta_v[ ++ sta_f] = minn ( minn ( 2 * sta_v[ the_2] , 3 * sta_v[ the_3] ) , minn ( 5 * sta_v[ the_5] , 7 * sta_v[ the_7] ) ) ;
the_2+ = ! ( sta_v[ sta_f] % 2 ) ;
the_3+ = ! ( sta_v[ sta_f] % 3 ) ;
the_5+ = ! ( sta_v[ sta_f] % 5 ) ;
the_7+ = ! ( sta_v[ sta_f] % 7 ) ;
}
while ( ( ask_n= input ( ) ) )
{
putchar ( 'T' ) ; putchar ( 'h' ) ; putchar ( 'e' ) ; putchar ( ' ' ) ;
output ( ask_n) ;
if ( ask_n% 10 <= 3 )
{
if ( ask_n% 100 > 10 && ask_n% 100 < 20 )
{
putchar ( 't' ) ; putchar ( 'h' ) ;
}
else
{
switch ( ask_n% 10 )
{
case 0 :
putchar ( 't' ) ; putchar ( 'h' ) ;
break ;
case 1 :
putchar ( 's' ) ; putchar ( 't' ) ;
break ;
case 2 :
putchar ( 'n' ) ; putchar ( 'd' ) ;
break ;
case 3 :
putchar ( 'r' ) ; putchar ( 'd' ) ;
break ;
}
}
}
else
{
putchar ( 't' ) ; putchar ( 'h' ) ;
}
putchar ( ' ' ) ;
putchar ( 'h' ) ;
putchar ( 'u' ) ;
putchar ( 'm' ) ;
putchar ( 'b' ) ;
putchar ( 'l' ) ;
putchar ( 'e' ) ;
putchar ( ' ' ) ;
putchar ( 'n' ) ;
putchar ( 'u' ) ;
putchar ( 'm' ) ;
putchar ( 'b' ) ;
putchar ( 'e' ) ;
putchar ( 'r' ) ;
putchar ( ' ' ) ;
putchar ( 'i' ) ;
putchar ( 's' ) ;
putchar ( ' ' ) ;
output ( sta_v[ ask_n] ) ;
putchar ( '.' ) ;
putchar ( '\n' ) ;
}
return 0 ;
}