1. 程式人生 > >codeforces 376C Divisible by Seven(能被7整除的數)

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

題目連結:

題目大意:

給一個很大的數,這個數一定包含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;
  }