题意:给你一个500000长度的数字,然后环形的让每位做头,例如123,就有123,231,312三个,然后问这n个数字的和S,S的最小非1因子是多少
题解:每个数字在每个位置都会有一次,如果说所有数字之和为A(1234的A就是10),那么原始长度为N的数,S就一定长成AAAAAAAAAAAAAA
也就是 S=A*10^0+A*10^1+A*10^2+...+A*10^(n-1)
10S= A*10^1+A*10^2+...+A*10^(n-1)+A*10^n
9S=A*10^n-A
那其实S就是A*1111111(n个1),也就是找A和111111(n个1)因子中最小的那个 这个数当然也一定是质数
对于A,我们知道500000*9=4500000,也就是A最大这么多,可以暴力sqrt(A),找到他最小的因子
但是对于11111(n个1),他的最小因子就没有规律,通过打表可以发现,除了每3项有一个可以被3整除,还常有11,41,并时不时的出现他自身(也就是说这个数是质数)
但是题目说了保证答案是小于5*10^6 所以我们可以预处理这范围内的所有素数,然后挨个判断能否被1111(n个1)整除
那这样其实我们就可以直接对S进行操作,不需要拆分了,S=(A*10^n-A)/9,枚举质因子p 意思就是要满足(A*10^n-A)%(9p)==0就行了
1 #include<bits/stdc++.h> 2 using namespace std; 3 char c; 4 int x,tot,ans; 5 int f[4500006]; 6 int pow(int a,int b,int mod) 7 { 8 if (b==1) return a; 9 long long t=pow(a,b/2,mod); 10 t=t*t%mod; 11 if (b%2) t=t*a%mod; 12 return t; 13 } 14 int check(int n,int s,int m) 15 { 16 int res=(pow(10,n,9*m)+9*m-1)%(9*m)/9; 17 return 1LL*res*s%m==0; 18 } 19 int main() 20 { 21 for(int i=2;i<4500005;i++) 22 if (!f[i]) 23 for(int j=i+i;j<4500005;j+=i) f[j]=1; 24 while (scanf("%c",&c)!=EOF) 25 { 26 if (c>='0' && c<='9') 27 { 28 tot++; 29 x+=c-'0'; 30 }else break; 31 } 32 for(int i=2;i<=4500000;i++) 33 if (!f[i] && check(tot,x,i)) 34 { 35 printf("%d",i); 36 return 0; 37 } 38 }