codeforces 376C Divisible by Seven(能被7整除的数)

题目链接:

http://codeforces.com/problemset/problem/376/C

题目大意:

给一个很大的数,这个数一定包含1,6,8,9这4个数字,当然可能还有其他数字。现在要重新排列这些数字获得一个新的数字,要求不出现前导零并且被7整除。

思路:

能被7整除的数,一定是有规律可循的。

先明确:10的零次幂除以7余1;
          10的一次幂除以7余3;
          10的二次幂除以7余2;
          10的三次幂除以7余6;
          10的四次幂除以7余4;
          10的五次幂除以7余5;
          10的六次幂除以7余1(循环了)、、、
对于任意一个数,用其相应位数乘以位数幂的余数,这几个数相加以后,看和能不能被7整除,如果能被整除那么这个数也一定能被整除。

比如343=3*2+4*3+3*1->21能被7整除。

那么再看这道题,因为一定有1,6,8,9这4个数字,而这4个数字的组合方式有24种。不同的组合我们可以发现他们除以7取余数的范围是0-6,也就是说,我们可以通过构造一个新的能被7整除的数来解决这个问题。

所以对于一个大数,我们可以先除去0,然后选出1,6,8,9这4种数字(每种只选一个),剩下的那些数字我们可以相加取模,那么就可以得到除以7以后的余数x。然后我们再把含有1,6,8,9的四位数放到后面,就是形成了[num][1689]的形式。那么num所处的位置是10的四次幂,所以我们可以计算出4*x,只要取[1689]中的某一个组合获得余数y,使得4*x+y能被7整除即可。


代码:

#include<stdio.h>
#include<string.h>
 char s[1000005],ans[1000005];
 char ap[10][5]={"1869","1968","1689","6198","1698","1986","1896"};  //分别代表余数从0-6的组合
int main()
{
  int i,j,k,l,num,f1,f2,f3,f4,t,sum;
  while(scanf("%s",&s)!=EOF)
  {
  	t=0;
  	sum=0;
  	f1=f2=f3=f4=1;
  	memset(ans,0,sizeof(ans));
  	num=0;
  	l=strlen(s);
  	for(i=0;i<l;i++)
  	if(s[i]=='0')num++;
  	for(i=0;i<l;i++)
  	{
  		if(s[i]=='0')continue;
	  	if(s[i]=='1'&&f1)
		  {f1--;continue;}	
		  if(s[i]=='6'&&f2){
  			f2--;
  			continue;
  		}
  		if(s[i]=='8'&&f3){
		  	f3--;
		  	continue;
		  }
		  if(s[i]=='9'&&f4){
  			f4--;
  			continue;
  		}
  		ans[t++]=s[i];
  		sum=(sum*10+s[i]-'0')%7;
	  	}
	  	printf("%s",ans);
	  	if(sum==0)printf("%s",ap[0]);
	  	if(sum==1)printf("%s",ap[3]);    //1*10000+y
	  	if(sum==2)printf("%s",ap[6]);
		if(sum==3)printf("%s",ap[2]);
		if(sum==4)printf("%s",ap[5]);
		if(sum==5)printf("%s",ap[1]);
		if(sum==6)printf("%s",ap[4]);
		for(i=0;i<num;i++)   //尾部添加0
		printf("0");
		printf("\n");   
	  }
	  return 0;
  }	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值