nyoj541 最强DE战斗力(数论&&大数问题)

其实这道题 自己写几个数找找规律就找到了  会发现把一个数尽可能的拆分为多个3,如果余1,把最后一个3加1,如果余2再乘以2.

这是一位大神的分析。点击打开链接

又因为这道题牵扯到大数  所以用字符串保存结果。


#include <stdio.h>
#include <string.h>
#define num 300
char str[num];//保存结果
int main()
{
	int test,j,t,i,k,n,m,r;
	scanf("%d",&test);
	while(test--)
	{
		memset(str,0,sizeof(str));
		str[0]=1;
		scanf("%d",&n);
		if(n<=4)
		printf("%d\n",n);
		else
		{
			m=n/3,r=n%3;//m判断有多少个3,r保存余数
			for(i=1;i<=m-1;i++)//先求3的m-1次方
			{
				for(j=0,t=0;j<num;j++)//用字符串保存
				{
					k=str[j]*3+t;//k保存当前相乘的结果
					str[j]=k%10;//当前字符保存为k%10的余数<span style="white-space:pre">	</span>
					t=k/10;//k/10为下一次字符的进位(可能说的不是太清楚 ,就是如果k>10,由于一个字符只能保存0-9的数,位大于10要进给下一)
				}
			}
			if(r==0||r==1)
			{
				if(r==1)//当余数为1,更新m+1=4.
				m=4;
				if(r==0)//为0的话,m不变,m=3
				m=3;
				for(j=0,t=0;j<num;j++)//乘以m
				{
					k=str[j]*m+t;
					str[j]=k%10;
					t=k/10;
				}
			}
			if(r==2)//如果余数为2,分两次计算,分别为乘以3,2
			{
				for(j=0,t=0;j<num;j++)//乘以3
				{
					k=str[j]*3+t;
					str[j]=k%10;
					t=k/10;
				}
				for(j=0,t=0;j<num;j++)//乘以2
				{
					k=str[j]*2+t;
					str[j]=k%10;
					t=k/10;
				}
			}
			for(i=num-1;i>=0;i--)//最后一个不是0的数,标记
			if(str[i]!=0)
			break;
			for(j=i;j>=0;j--)
			printf("%d",str[j]);
			printf("\n");
		}
	}
	return 0;
}        


你可能感兴趣的:(nyoj,541,nyoj541)