hihoCoder-1839 榶榶榶 数学

题面

题意:给你一个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 }

 

posted @ 2018-09-24 00:33  口香糖万岁  阅读(325)  评论(0编辑  收藏  举报