POJ 1309

题意: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 }

你可能感兴趣的:(poj)