【SHNU_RUSHer】动态规划 [Cloned]B - Humble Numbers【丑数模板】【数的组合模板】

26 篇文章 1 订阅
26 篇文章 0 订阅

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\} min{nsta_v[the_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,其余的末尾是13的不是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;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值