RGB简单着色问题——雨花石项链(字符数组的相加——以整数的规则)

第一次写博客,引发我写博客的动机就是,我发现我实在是太蠢了,昨天下午一道5分钟可以敲完的题目,我硬生生敲了四个多小时,编程真的是一个很奇妙的事情我只能说。。

下面我主要来分享一下我的脑残行为。

首先给出题目:

Description

人称AC之神的QIGe最近一直忙着培养NOI高手,为了鼓励NOI高手, QiGe做了若干雨花石项链,作为对表现优秀的选手的奖励.他会挑选一个雨花石作为这串项链的开始,然后一个接一个连起来,现在他有三种颜色的雨花石,红(Red)、绿(Green)、蓝(Blue),做项链的时候他要求每相邻的2个雨花石不能相同的颜色,尽管最后一步把首尾连接起来的工作QiGe不需要去做,但也必须保证首尾2个雨花石它们是不同颜色。你知道QiGe有多少种串项链的方法吗?

Input

输入数据包含多个测试实例,每个测试实例占一行,由一个整数N组成,(0<n<=50)。

Output

对于每个测试实例,请输出全部的满足要求的排法,每个实例的输出占一行。

Sample Input

1
2

Sample Output

3
6

这道题目的难点其实就是在算法思路这一块,也就是需要找到其中的规律,说句实话,如果没有经常接触这类题目,新手一接触确实会一头雾水,就比如我一开始接触这道题目,真的非常自闭,感觉自己水平还有很大很大的提升空间。

我这篇文章不会重点讲算法,因为算法只要给出了,自己再想想就非常简单。

算法:

设n个石头围成项链种类为a[n],根据题目要求一开始就定义int a[50],然后根据规律可以得出a[n]=a[n-1]+a[n-2]*2(这里不懂的话可以看下这位兄弟的博客,https://blog.csdn.net/zstuyyyyccccbbbb/article/details/103840127)
然后是不是就很简单了?对,没错,我也是这么觉得的,但是我犯了一个致命的错误,希望后来人不要和我一样,浪费了四个小时!

下面是我花了四个小时写的非常麻烦的代码。

为什么说麻烦?因为本来这个问题可以用整型加个for循环一下子就解决了,但是这里面有个小bug,就是从第32个开始,整数就会很大很大,导致超过整型的范围,但幼小天真的我仅仅只能找到long这个类型,结果还是太小,最后我竟然愚蠢的放弃了这条最简单的道路,走向了荆棘丛生的杂草堆,能让我专门写一篇文章来骂我自己的愚蠢😀。

我的愚蠢想法就是既然整型存储不了的话,那么就用字符型存储呗,于是我踏上了这条不归路,这个过程可以说是相当曲折,我没有时间在这里一一阐述,就给出相应的代码和注释,如果有看的下去的兄弟应该能发现我的愚蠢。。

愚蠢代码

#include <stdio.h>
#include<string.h>
int main()
{
	char a[50][100]={"3","6","6"};
	int i;
	for(i=3;i<50;i++) 	/*生成前五十个结果*/
	{
		cal_char(a,a[i-1],a[i-2],i);
	}
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		printf("%s\n",a[n-1]);
	}
}
	void cal_char(char a[][100],char b[],char c[],int i) /*这里有个小细节,就是第一个变量不能写成a[][],要不然用字符串函数赋值的时候会出问题*/
{
	char d[100],o[100]; /*d用来当作赋值的中介,o是c的复制品*/
	strcpy(o,c);	/*之所以要有复制品,是因为之后要让b,c俩个数组长度对齐,不足的地方补0,为了不影响最后的输出,因此不能直接改变c的值*/
	int len_b=strlen(b),len_o=strlen(o);  	/*确定俩个数组长度*/
	while(strlen(b)!=len_o)		/*让俩个长度对齐*/
	{
		int j;
		for(j=len_o;j>=1;j--)
		{
			o[j]=o[j-1];
		}
		o[0]='0';
		len_o++;
	}
	o[len_o]='\0';
	int j=len_b-1,forward=0;	/*用j指向b和c的最后一个字符,forward是进位*/ 
	d[len_b+1]='\0';	/*初始化间接数组*/
	for(j;j>=0;j--)		/*这个计算的过程很简单,大家应该随便看看就会了*/
	{
		int x;
		x=b[j]-'1'+1+(o[j]-'1'+1)*2+forward;
		forward=0;
		if(x>=10)
		{
			forward=x/10;
			x=x%10;		
		}
		char y=x+'0';
		d[j+1]=y;  /*这里面d的第一位要留出来,因为之后有可能要加上1*/
	}	
	if(forward==1)	/*要加1的情况*/
	{
		d[0]='1';
		strcpy(a[i],d);		
	}
	else	/*不要加1的情况,此时把j整体向前移动一位*/
	{
		int j;
		for(j=0;d[j]!='\0';j++)
		{
			d[j]=d[j+1];
		}
		strcpy(a[i],d);		
	}
}

是不是很麻烦?对,没错,麻烦的不行。。
之后我才从一位兄弟那边得知,一开始的时候若是我改成long long型,就能容得下这么大的数了,也不用向我这样花里胡哨搞半天。
我。。。。。。。。。。。
下面给出代码。

正常代码

#include <stdio.h>
#include<string.h>
int main()
{
	long long a[50];
	a[0]=3;
	a[1]=6;
	a[2]=6;
	int i;
	for(i=3;i<50;i++)
	{
		a[i]=a[i-1]+a[i-2]*2;
	}
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		printf("%lld\n",a[n-1]);
	}
}

是不是感觉很简单?
写到这里我真的感觉我蠢得不行!真的是任重道远啊。真的还有很多不足,昨天经历了一个晚上的自闭,今天还是得爬进来补作业,尽管生活很难,但还得坚持,我不知道这样有没有意义,我只是不想体验放弃的感觉。。。

首先声明,我写博客很大程度是为了记录和分享我的编程之路,如果后来人是在百度上面搜到我的文章,动机不是为了知识本身,而是为了应付题目的话,我话摆在这里,借鉴可以,但是一定要转化成自己的知识,不要只抄,然后没弄懂,那还不如直接花钱请人帮你做了,我一直秉持的原则就是,你真不想干某件事,而这件事又在你看来是没有意义的话,倒还不如用钱解决,说白了就是用钱买时间,没有必要在一些对你没有意义的地方花过多时间,倒还不如用这么点时间去做一些更有意义的事情

如果觉得有帮助,可以关注一下我的公众号,我的公众号主要是将这些文章进行美化加工,以更加精美的方式展现出来,同时记录我大学四年的生活,谢谢你们!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值