数论基础小记

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

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

 

 

你可能感兴趣的:(基础)