国色天香(火柴,c++)

国色天香(match.pas/c/cpp)

庭前芍药妖无格,池上芙蕖净少情。唯有牡丹真国色,花开时节动京城。
——唐· 刘禹锡《赏牡丹》

芍药花再红终究妖艳无格。终不及牡丹,国色天香。
——乌拉那拉氏宜修

华妃总是想要用自己的气焰打压皇后,正好有一天,皇上有兴趣来玩一个火柴游戏,让华妃和皇后都来参与。规则如下:这是火柴所形成 9 个数字的方式,每个数字所需的火柴数量不一样。现在皇上给每个人发了 N 根火柴,华妃要摆出其所能摆出最小的数,而皇后则需要摆出其所能摆出的最大的数。当然,皇上是不容糊弄的,前导 0 或者摆出不规则的数字什么的都算是作弊。获胜者的奖励则是皇上今晚会翻她的牌子。现在皇后与华妃都使出浑身解数,而在一旁观看的甄嬛则想尽快知道答案。






是了,老师出的题比较奇葩……


这道题我个人觉得是贪心。

且听王三岁解释一下:

1.每一个数字的所用火柴棒数量是固定的,也就是我们可以分为10种情况——虽然10种情况并不多,可是有很多个人感觉用不到

2.最大最大最小值有一定的特殊性,我感觉是有规律的


3.最重要的是……用DP和图论感觉大材小用了,而枚举就是10^10,超了而且写着烦  (´Д` )


那么我们来探索一下最大最小值的特殊性:


最大值:

1)很容易想到要用最少的火柴来拼最大的数字

2)从常识的角度来看,位数越多拼出的数字就越大

3)从数学的角度来讲,越大的数字放在越高的位上数字整体就会更大


分析完以后

我们可以这么写

首先找到火柴的总数n

因为最少需要两个火柴能拼出一位数1

所以先除二

附代码:

int a[10001]={0};
int max(int n)
{
	int c,lenth=0;
	lenth=n/2;
	for(int i=1;i<=lenth;i++)
	{
		a[i]=1;
	}
	c=n%2;
	if(c==1)
	{
		a[1]=7;
	}
	return lenth;
}

好了以上是求最大值。



接下来是最小值:

1)首先是位数最少;

2)每一位尽可能多的消耗火柴;

3)小的尽量排前面;


每一位能消耗的最大值就是7根火柴,召唤出一个8(莫名中二病犯了)

然后我们同样取余数c

这个时候就有趣了:


如果余数为3:

            1)如果剩一个八:从8拿两个火柴可以组成22而不是78

            2)如果剩两个八:从两个8拿两根火柴可以组成200

如果余数为4:

            1)如果有一个八:取一个变成20而不是48

如果余数为6:

             1)如果为第一位:取6而不是0

如果余数为1:

              1)如果有一个八:取一个变成10


附上召唤王三岁的代码:(为方便可读性没有简化代码)

int b[1001]={0};
int min(int n)
{
	int c,lenth=0;
	lenth=n/7;
	for(int i=1;i<=lenth;i++)
	{
		b[i]=8;
	}
	c=n%7;
	if(c==0)
	{
		return lenth;
	}
	if(c==3)
	{
		if(lenth>=2)
		{
			b[lenth]=0;
			b[lenth-1]=0;
			lenth++;
			b[lenth]=2;
			return lenth;
		}
		if(lenth==1)
		{
			b[lenth]=2;
			lenth++;
			b[lenth]=2;
			return lenth;
		}
		if(lenth==0)
		{
			lenth++;
			b[lenth]=7;
			return lenth;
		}
	}
	if(c==4)
	{
		if(lenth>=1)
		{
			b[lenth]=0;
			lenth++;
			b[lenth]=2;
			return lenth;
		}
		lenth++;
		b[lenth]=4;
		return lenth;
	}
	if(c==6)
	{
		lenth++;
		b[lenth]=6;
		return lenth;
	}
	if(c==1)
	{
		if(lenth>=1)
		{
			b[lenth]=0;
			lenth++;
			b[lenth]=1;
			return lenth;
		}
	}
	else
	{
		lenth++;
		if(c==2)
		{
			b[lenth]=1;
		}
		if(c==5)
		{
			b[lenth]=2;
		}
		return lenth;
	}
}


好了这是最符合刚刚思考过程的代码。

当然还有简化版只有35行(然而因为思路会有所改动所以没给出)

lenth被返回后倒序输出b数组即可

好了王三岁讲完了
谢谢观看♪(´ε`)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值