题意:m个椰子,n个人,使得这n个人按次序醒来后能够将剩余的椰子分成n份多1,然后将1扔给猴子,自己拿走n份中的一份(这里的n一旦确定就不会改变),n次之后,剩余的椰子还能被n整除,求最大满足条件的n。

题解:考虑第一次m%n==1,所以对m-1分解质因数,即m-1的所有非1的约数都能在第一次分椰子的时候满足条件,然后枚举所有m-1的约数,最多2000多个,找出最大的。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int mr=(1<<16)+1;
 6 bool notp[mr];
 7 int pr[mr];
 8 int pn;
 9 void getpri()
10 {
11     pn=0;
12     memset(notp,0,sizeof(notp));
13     for(int i=2; i<mr; i++)
14     {
15         if(!notp[i])
16         {
17             pr[pn++]=i;
18         }
19         for(int j=0; j<pn && i*pr[j]<mr; j++)
20         {
21             int k=i*pr[j];
22             notp[k]=1;
23             if(i%pr[j]==0)
24             {
25                 break;
26             }
27         }
28     }
29 }
30 int fac[100];
31 int tot[100],top;
32 void div(int n)
33 {
34     for(int i=0;i<pn&&pr[i]*pr[i]<=n;i++)
35     {
36         if(n%pr[i]==0)
37         {
38             fac[top]=pr[i];
39             tot[top]=0;
40             while(n%pr[i]==0)
41             {
42                 tot[top]++;
43                 n/=pr[i];
44             }
45             top++;
46         }
47     }
48     if(n>1)
49         fac[top]=n,tot[top++]=1;
50 }
51 bool solve(int m,int n)
52 {
53     for(int i=0;i<n;i++)
54     {
55         if(m%n!=1)
56             return false;
57         m=(m-1)/n*(n-1);
58     }
59     return m%n==0;
60 }
61 int ans;
62 int po(int n,int k)
63 {
64     int p=1;
65     while(k--)
66         p*=n;
67     return p;
68 }
69 void dfs(int k,int res,int m)
70 {
71     if(k==top)
72     {
73         if(solve(m,res))
74             ans=max(ans,res);
75         return;
76     }
77     for(int i=tot[k];i>=0;i--)
78         dfs(k+1,res*po(fac[k],i),m);
79 }
80 int main()
81 {
82     getpri();
83     int m;
84     while(scanf("%d",&m),m>=0)
85     {
86         int mm=m-1;
87         top=0;
88         div(mm);
89         ans=-1;
90         dfs(0,1,m);
91         if(ans==-1)
92             printf("%d coconuts, no solution\n",m);
93         else
94             printf("%d coconuts, %d people and 1 monkey\n",m,ans);
95     }
96     return 0;
97 }