数论基础小记

对于数论 首先要提的当然是素数了 先从素数开始 这里的题目大部分来自网上一大神的数学题的总结   自己挑了一部分拿来练习

POJ 2689 Prime Distance  经典的区间素数筛选 

一般看题的时候重点会看下数据范围 这题明显告诉你了l u 差不超过100W 那就想到可以从这里入手 对于100W内的素数我们是可以很快筛出来的 21Y就不太可能了 

所以可以转换下 先把47000内的素数打表筛出来 然后再用这些素数去筛 l-u内的素数 筛法与筛小的类似 因为差不超过100W 所以是可以很快解决掉的

注意一下 有1的情况吧

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 47000
12 #define M 1000010
13 #define LL long long
14 #define INF 0xfffffff
15 const double eps = 1e-8;
16 const double pi = acos(-1.0);
17 const double inf = ~0u>>2;
18 int p[N],g;
19 LL res[M];
20 bool f[N+10];
21 bool v[M];
22 void init()
23 {
24     int i,j;
25     for(i = 2 ; i<= N ; i++)
26     {
27         if(!f[i])
28         {
29             for(j = i+i ; j <= N;j+=i)
30             f[j] = 1;
31             p[++g] = i;
32         }
33     }
34 }
35 int main()
36 {
37     LL i,j;
38     LL l,u;
39     init();
40     while(scanf("%lld%lld",&l,&u)!=EOF)
41     {
42         memset(v,0,sizeof(v));
43         int o=0;
44         LL y;
45         for(i = 1; i <= g ; i++)
46         {
47            if(l%p[i])
48            {
49                y = (l/p[i]+1)*p[i];
50            }
51            else y = l;
52            for(j = y ; j <= u ; j+=p[i])
53                if(j!=p[i])
54                v[j-l] = 1;
55         }
56         if(l==1) v[0] = 1;
57         for(i = l ; i <= u; i++)
58         if(!v[i-l])
59         {
60             res[++o] = i;
61         }
62         if(o<2)
63         {
64             puts("There are no adjacent primes.");
65             continue;
66         }
67         LL minz=M,st,en,ss,ee,maxz=0;
68         for(i = 1; i < o ; i++)
69         {
70             if(res[i+1]-res[i]<minz)
71             {
72                  minz = res[i+1]-res[i];
73                  st = res[i];
74                  en = res[i+1];
75             }
76             if(res[i+1]-res[i]>maxz)
77             {
78                  maxz = res[i+1]-res[i];
79 
80                  ss = res[i];
81                  ee = res[i+1];
82             }
83         }
84         printf("%lld,%lld are closest, %lld,%lld are most distant.\n",st,en,ss,ee);
85     }
86     return 0;
87 }
View Code

 

 ZOJ 2562 More Divisors 反素数

定义

  对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.

性质

  性质一:一个反素数的质因子必然是从2开始连续的质数. 

  性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....

这道题就是反素数的一个应用 这样约数肯定是最多的 数的算法就组合一下就可以了

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 #define LL long long
10 int p[110];
11 LL tsum,ans,n;
12 int init(int x)
13 {
14     int i;
15     for(i = 2; i <= sqrt(x) ; i++)
16     if(x%i==0) return 0;
17     return 1;
18 }
19 void dfs(LL ts,LL sum,int o,int v)
20 {
21     if(sum>tsum)
22     {
23         tsum = sum;
24         ans = ts;
25     }
26     if(sum==tsum) ans = min(ans,ts);
27     for(int i = 1 ;i <= o ; i++)
28     {
29         if(ts*pow(p[v+1],i)>n) break;
30         dfs(ts*pow(p[v+1],i),sum*(i+1),i,v+1);
31     }
32 }
33 int main()
34 {
35     int i,g=0;
36     p[++g] = 2;
37     for(i = 3; i <= 100 ; i++)
38     if(init(i))
39     p[++g] = i;
40     while(cin>>n)
41     {
42         ans = 1;
43         LL x = n;
44         int o = 0;
45         tsum=0;
46         while(x)
47         {
48             o++;
49             x/=2;
50         }
51         //cout<<o<<endl;
52         for(i = 1;  i< o ;i++)
53         {
54             dfs(pow(2,i),i+1,i,1);
55         }
56         cout<<ans<<endl;
57     }
58     return 0;
59 }
View Code

POJ 1811 Prime Test 大素数的测试 算法导论上 章31.8  Miller Rabin素数判定及pollard_rho分解

这样的直接记模板好了 反正不会再有什么变形了  

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 #include<ctime>
 11 using namespace std;
 12 #define N 100000
 13 #define LL long long
 14 #define INF 0xfffffff
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int S = 20;
 19 LL fc[N];
 20 int g;
 21 LL muti_mod(LL a,LL b,LL n)
 22 {
 23     a%=n;
 24     b%=n;
 25     LL ret = 0;
 26     while(b)
 27     {
 28         if(b&1)
 29         {
 30             ret+=a;
 31             if(ret>=n) ret-=n;
 32         }
 33         a<<=1;
 34         if(a>=n) a-=n;
 35         b>>=1;
 36     }
 37     return ret;
 38 }
 39 LL exp_mod(LL a,LL n,LL b)
 40 {
 41     if(n==1) return a%b;
 42     int bit[64],k=0;
 43     while(n)
 44     {
 45         bit[k++] = n&1;
 46         n>>=1;
 47     }
 48     LL ret = 1;
 49     for(k = k-1; k>= 0 ; k--)
 50     {
 51         ret = muti_mod(ret,ret,b);
 52         if(bit[k]==1) ret = muti_mod(ret,a,b);
 53     }
 54     return ret;
 55 }
 56 bool check(LL a,LL n,LL x,int t)
 57 {
 58     LL ret = exp_mod(a,x,n),last = ret;
 59     for(int i = 1; i <= t; i++)
 60     {
 61         ret = muti_mod(ret,ret,n);
 62         if(ret==1&&last!=1&&last!=n-1) return 1;
 63         last = ret;
 64     }
 65     if(ret!=1) return 1;
 66     return 0;
 67 }
 68 bool miller_rabin(LL n)
 69 {
 70     LL x = n-1;int t = 0;
 71     while((x&1)==0) {x>>=1;t++;}
 72     bool flag = 1;
 73     if(t>=1&&(x&1)==1)
 74     {
 75         for(int i = 0 ; i < S ;i++)
 76         {
 77             LL a = rand()%(n-1)+1;
 78             if(check(a,n,x,t)){flag = 1;break;}
 79             flag = 0;
 80         }
 81     }
 82     if(!flag||n==2) return 0;
 83     return 1;
 84 }
 85 LL gcd(LL a ,LL b)
 86 {
 87     if(a==0) return 1;
 88     if(a<0) return gcd(-a,b);
 89     while(b)
 90     {
 91         LL t = a%b;a = b;b = t;
 92     }
 93     return a;
 94 }
 95 LL pollard_rho(LL x,LL c)
 96 {
 97     LL i=1,x0 = rand()%x,y = x0,k=2;
 98     while(1)
 99     {
100         i++;
101         x0 = (muti_mod(x0,x0,x)+c)%x;
102         LL d = gcd(y-x0,x);
103         if(d!=1&&d!=x)
104         return d;
105         if(y==x0) return x;
106         if(i==k)
107         {
108             y = x0;
109             k+=k;
110         }
111     }
112 }
113 void findfac(LL n)
114 {
115     if(!miller_rabin(n))
116     {
117         fc[++g] = n;
118         return ;
119     }
120     LL p = n;
121     while(p>=n) p = pollard_rho(p,rand()%(n-1)+1);//cout<<p<<endl;
122     findfac(p) ;
123     findfac(n/p);
124 }
125 int main()
126 {
127     srand(time(NULL));
128     int i,t;
129     LL n;
130     scanf("%d",&t);
131     while(t--)
132     {
133         g = 0;
134         scanf("%lld",&n);
135         if(!miller_rabin(n))
136         puts("Prime");
137         else
138         {
139             findfac(n);
140             LL minz = n;
141             for(i = 1; i <= g ;i++)
142             minz = min(minz,fc[i]);
143             printf("%lld\n",minz);
144         }
145     }
146     return 0;
147 }
View Code

POJ 2429 GCD & LCM Inverse  也是同上 pollard_rho分解 然后取最小

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 #include<ctime>
 11 using namespace std;
 12 #define N 100000
 13 #define LL long long
 14 #define INF 0xfffffff
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int S = 20;
 19 LL fc[N],o[100];
 20 int g;
 21 LL muti_mod(LL a,LL b,LL n)
 22 {
 23     a%=n;
 24     b%=n;
 25     LL ret = 0;
 26     while(b)
 27     {
 28         if(b&1)
 29         {
 30             ret+=a;
 31             if(ret>=n) ret-=n;
 32         }
 33         a<<=1;
 34         if(a>=n) a-=n;
 35         b>>=1;
 36     }
 37     return ret;
 38 }
 39 LL exp_mod(LL a,LL n,LL b)
 40 {
 41     if(n==1) return a%b;
 42     int bit[64],k=0;
 43     while(n)
 44     {
 45         bit[k++] = n&1;
 46         n>>=1;
 47     }
 48     LL ret = 1;
 49     for(k = k-1; k>= 0 ; k--)
 50     {
 51         ret = muti_mod(ret,ret,b);
 52         if(bit[k]==1) ret = muti_mod(ret,a,b);
 53     }
 54     return ret;
 55 }
 56 bool check(LL a,LL n,LL x,int t)
 57 {
 58     LL ret = exp_mod(a,x,n),last = ret;
 59     for(int i = 1; i <= t; i++)
 60     {
 61         ret = muti_mod(ret,ret,n);
 62         if(ret==1&&last!=1&&last!=n-1) return 1;
 63         last = ret;
 64     }
 65     if(ret!=1) return 1;
 66     return 0;
 67 }
 68 bool miller_rabin(LL n)
 69 {
 70     LL x = n-1;int t = 0;
 71     while((x&1)==0) {x>>=1;t++;}
 72     bool flag = 1;
 73     if(t>=1&&(x&1)==1)
 74     {
 75         for(int i = 0 ; i < S ;i++)
 76         {
 77             LL a = rand()%(n-1)+1;
 78             if(check(a,n,x,t)){flag = 1;break;}
 79             flag = 0;
 80         }
 81     }
 82     if(!flag||n==2) return 0;
 83     return 1;
 84 }
 85 LL gcd(LL a ,LL b)
 86 {
 87     if(a==0) return 1;
 88     if(a<0) return gcd(-a,b);
 89     while(b)
 90     {
 91         LL t = a%b;a = b;b = t;
 92     }
 93     return a;
 94 }
 95 LL pollard_rho(LL x,LL c)
 96 {
 97     LL i=1,x0 = rand()%x,y = x0,k=2;
 98     while(1)
 99     {
100         i++;
101         x0 = (muti_mod(x0,x0,x)+c)%x;
102         LL d = gcd(y-x0,x);
103         if(d!=1&&d!=x)
104         return d;
105         if(y==x0) return x;
106         if(i==k)
107         {
108             y = x0;
109             k+=k;
110         }
111     }
112 }
113 void findfac(LL n)
114 {
115     if(!miller_rabin(n))
116     {
117         fc[g++] = n;
118         return ;
119     }
120     LL p = n;
121     while(p>=n) p = pollard_rho(p,rand()%(n-1)+1);//cout<<p<<endl;
122     findfac(p) ;
123     findfac(n/p);
124 }
125 int main()
126 {
127     srand(time(NULL));
128     int i,j;
129     LL n,m;
130     while(scanf("%lld %lld",&n,&m)!=EOF)
131     {
132         g = 0;
133         LL s = m/n;
134         if(m==n)
135         {
136             printf("%lld %lld\n",n,n);
137             continue;
138         }
139         findfac(s);
140         LL minz = s+2;
141         LL ans;
142         sort(fc,fc+g);
143         int ko = 0;
144         o[0] = fc[0];
145         for(i = 1 ; i < g ; i++)
146         if(fc[i]!=fc[i-1])
147         {
148             ko++;
149             o[ko] = fc[i];
150             //cout<<o[ko]<<endl;
151         }
152         else o[ko]*=fc[i];
153         for(i = 0 ; i < (1<<ko) ; i++)
154         {
155             LL y = 1;
156             for(j = 0; j < ko ; j++)
157             {
158                 if(i&(1<<j))
159                 y*=o[j];
160             }
161             LL x = s/y;
162             if(minz>x+y)
163             {
164                 ans = x;
165                 minz = x+y;
166             }
167         }
168         LL x = s/ans;
169         if(ans>x)
170         swap(ans,x);
171         printf("%lld %lld\n",ans*n,x*n);
172     }
173     return 0;
174 }
View Code

POJ 1284 Primitive Roots  求一个素数的原根的个数 欧拉函数 讲解

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int euler(int x)
18 {
19     int s = x;
20     for(int i= 2 ; i*i <= x ; i++)
21     {
22         if(x%i==0)
23         {
24             s-=s/i;
25             while(x%i==0)
26             x/=i;
27         }
28     }
29     if(x!=1)
30     s-=s/x;
31     return s;
32 }
33 int main()
34 {
35     int p;
36     while(cin>>p)
37     {
38         int ans = euler(p-1);
39         cout<<ans<<endl;
40     }
41     return 0;
42 }
View Code

POJ 2407 Relatives 欧拉函数

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int euler(int x)
18 {
19     int s = x;
20     for(int i= 2 ; i*i <= x ; i++)
21     {
22         if(x%i==0)
23         {
24             s-=s/i;
25             while(x%i==0)
26             x/=i;
27         }
28     }
29     if(x!=1)
30     s-=s/x;
31     return s;
32 }
33 int main()
34 {
35     int p;
36     while(cin>>p)
37     {
38         if(!p) break;
39         int ans = euler(p);
40         cout<<ans<<endl;
41     }
42     return 0;
43 }
View Code

POJ 2478 Farey Sequence 欧拉函数

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 1000010
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 LL sum[N];
18 int p[N],g;
19 bool f[N];
20 void init()
21 {
22     int i,j;
23     for(i = 2; i <= N-10 ; i++)
24     {
25         if(!f[i])
26         {
27             for(j = i+i ; j <= N-10 ;j+=i)
28             f[j] = 1;
29             p[++g] = i;
30         }
31     }
32 }
33 int euler(int x)
34 {
35     int s = x;
36     for(int i= 1 ; p[i]*p[i] <= x ; i++)
37     {
38         if(x%p[i]==0)
39         {
40             s-=s/p[i];
41             while(x%p[i]==0)
42             x/=p[i];
43         }
44     }
45     if(x!=1)
46     s-=s/x;
47     return s;
48 }
49 int main()
50 {
51     int n,i;
52     init();
53     for(i = 2; i <= N-10 ; i++)
54     sum[i] = sum[i-1]+euler(i);
55     //cout<<",";
56     while(cin>>n)
57     {
58         if(!n) break;
59         cout<<sum[n]<<endl;
60     }
61     return 0;
62 }
View Code

POJ 3090 Visible Lattice Points 水题 枚举下互质的

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 1010
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int sum[N][N];
18 int gcd(int a,int b)
19 {
20     return b==0?a:gcd(b,a%b);
21 }
22 void init()
23 {
24     int i,j;
25     for(i = 1; i <= N-10 ; i++)
26     {
27         for(j = 1 ; j <= N-10 ; j++)
28         if(gcd(i,j)==1)
29         sum[i][j] = sum[i][j-1]+1;
30         else
31         sum[i][j] = sum[i][j-1];
32     }
33 }
34 int main()
35 {
36     int i,j,c,n,kk=1;
37     init();
38     cin>>c;
39     while(c--)
40     {
41         cin>>n;
42         int ans = 2;
43         for(i = 1; i <= n;i++)
44         {
45             ans+=sum[i][n];
46         }
47         printf("%d %d ",kk++,n);
48         cout<<ans<<endl;
49     }
50     return 0;
51 }
View Code

POJ 3358 Period of an Infinite Binary Expansion 

 SGU 106 The equation 扩展欧几里得 不错的一道题 (组解的求解)

各种不细心及没考虑到。。

利用扩展欧几里得可以求得一组解 本题是求得满足x,y范围的解 

设p,q为求得的一组解

由定理可知 方程的所有解可表示为 x = p+b/gcd(a,b)*t,y = q-a/gcd(a,b)*t  t = {...-2.-1.0.1.2....}  证明

然后就可以求解了 分几种情况

1、a==0&&b==0    if(c==0)  (x2-x1+1)*(y2-y1+1) else 0;

2、a==0 if(c/a>=x1&&c/a<=x2&&c%a==0) y2-y1+1 else 0 ;  b==0类似

3、就是由上面的定理来写了 由[x1,x2]确定出来的t的范围[t1,t2]以及由[y1,y2]确定出来的[t3,t4]求下交集 

注意要对t1、t3取上界  比如2.5 应取3 而不是默认的2.

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 LL gcd(LL a,LL b)
18 {
19     return b==0?a:gcd(b,a%b);
20 }
21 void exgcd(LL a,LL b,LL &x,LL &y)
22 {
23     if(b==0)
24     {
25         x = 1;y = 0;
26         return ;
27     }
28     exgcd(b,a%b,x,y);
29     LL t = x;
30     x = y;
31     y = t-a/b*y;
32 }
33 int main()
34 {
35     LL x1,x2,y1,y2,a,b,c;
36     double d1,d2,d3,d4;
37     int t1,t2,t3,t4;
38     while(cin>>a>>b>>c)
39     {
40         cin>>x1>>x2>>y1>>y2;
41         LL x,y;
42         c = -c;
43         if (c<0) {a=-a;b=-b;c=-c;}
44         if (a<0) {a=-a;LL t=x1;x1=-x2;x2=-t;}
45         if (b<0) {b=-b;LL t=y1;y1=-y2;y2=-t;}
46         if(a==0&&b==0)
47         {
48             if(c==0)
49             cout<<(y2-y1+1)*(x2-x1+1)<<endl;
50             else
51             cout<<"0\n";
52             continue;
53         }
54         int k = gcd(a,b);
55         if(c%k!=0)
56         {
57             cout<<"0\n";
58             continue;
59         }
60         c/=k;
61         a/=k,b/=k;
62         exgcd(a,b,x,y);
63         x*=c;y*=c;
64         if(a==0||b==0)
65         {
66             if(a==0)
67             {
68                 if(c/b>=y1&&c/b<=y2&&c%b==0)
69                 cout<<x2-x1+1<<endl;
70                 else
71                 cout<<"0\n";
72             }
73             else
74             {
75                 if(c/a>=x1&&c/a<=x2&&c%a==0) cout<<y2-y1+1<<endl;
76                 else cout<<"0\n";
77             }
78             continue;
79         }
80         else
81         {
82             d1 = (x1-x)*1.0/b,d2 = (x2-x)*1.0/b;
83             d3 = (y-y2)*1.0/a,d4 = (y-y1)*1.0/a;
84         }
85         t1 = ceil(d1),t2 = floor(d2);
86         t3 = ceil(d3),t4 = floor(d4);
87         int l = max(t1,t3);
88         int r = min(t2,t4);
89         if(l>r) cout<<"0\n";
90         else cout<<r-l+1<<endl;
91     }
92     return 0;
93 }
View Code

 POJ 1781 In Danger  约瑟夫问题 

详见另一篇博客

POJ 3517 And Then There Was One   纯约瑟夫问题

与上篇类似   这一类 都可以以这个公式来写  f[1] = 0; f[i]  = (f[i-1]+m)%i;  证明见这篇

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int f[100100];
18 int main()
19 {
20     int i,j,n,m,k;
21     while(cin>>n>>k>>m)
22     {
23         if(!n&&!m&&!k) break;
24         f[1] = 0;
25         for(i = 2 ; i < n;i++)
26         {
27             f[i] = (f[i-1]+k)%i;
28             //cout<<f[i]<<endl;
29         }
30         f[n] = (f[n-1]+m)%n;
31         cout<<f[n]+1<<endl;
32     }
33     return 0;
34 }
View Code

 

POJ 1012 Joseph  约瑟夫  暴力解决 枚举M

 有个不错的剪枝 有n个好孩 1个坏孩的时候 下一次要杀掉坏孩 必定从坏孩 或者第一个好孩开始数 那么循环节要么是(n+1)*k 要么是(n+2)*k

 

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 100000
#define LL long long
#define INF 0xfffffff
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = ~0u>>2;
int f[30];
int o[30];
int init(int n)
{
    int i,j,ii;
    for(i = 0; i < 2*n ; i++)
    f[i] = i;
    for(i = n+1;;i+=n+1)
    {
        int t,ff=0;
        int k = 2;ii=i;
        while(k--)
        {
            t = 0;
            for(j = 0 ; j < 2*n ; j++)
            f[j] = j;
            for(j = 1 ; j <= n ;j++)
            {
                t = (t+ii-1)%(2*n-j+1);
                if(f[t]<n) break;
                int o = n;
                for(int g = n ; g < 2*n-j+1 ; g++)
                if(g==t) continue;
                else
                f[o++] = f[g];
            }
            //cout<<i<<" "<<ii<<" "<<j<<endl;
            if(j>n) {ff = 1;break;}
            ii++;
        }
        if(ff) break;
    }
    return ii;
}
int main()
{
    int i,j,n;
    for(i = 1 ; i <= 13 ; i++)
    o[i] = init(i);
    while(cin>>n)
    {
        if(!n) break;
        cout<<o[n]<<endl;
    }
    return 0;
}
View Code

POJ 2244 Eeny Meeny Moo  约瑟夫逆问题 给出你最后j(n) 求最小的m值  暴力枚举 结合上面的推导公式

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 100000
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 int f[155],o[155];
18 int init(int n)
19 {
20     int i,j;
21     for(i = 1; ;i++)
22     {
23         f[1] = 0;
24         for(j = 2 ;j < n; j++)
25         f[j] = (f[j-1]+i)%j;
26         f[n] = (f[n-1]+1)%j;
27         //cout<<f[n]<<endl;
28         if(f[n]+1==2)  return i;
29     }
30 }
31 int main()
32 {
33     int i,n;
34     init(3);
35     for(i = 3; i < 150 ; i++)
36     o[i] = init(i);
37     while(cin>>n)
38     {
39         if(!n) break;
40         cout<<o[n]<<endl;
41     }
42     return 0;
43 }
View Code

 

 

转载于:https://www.cnblogs.com/shangyu/p/3585324.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值