Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3349 | Accepted: 1405 |
Description
Input
Output
Sample Input
4 5 -1
Sample Output
21 39
这道题和poj2409基本上是一模一样的,都是模板型题,用c种颜色的珠子组成长度为s的项链,经典polya计数问题。只不过这道题c=3。
代码:
语言:c++
#include<iostream> using namespace std; int main() { long long gcd(long long a,long long b); long long s; while(cin>>s) { if(s==0) { cout<<0<<endl; continue; } if(s==-1)break; int k; long long p[64]; p[0]=1; for(k=0;k<s;++k) p[k+1]=p[k]*3; long long count=s&1?s*p[s/2+1]:(s/2)*(p[s/2]+p[s/2+1]); for(k=1;k<=s;++k) count+=p[gcd(k,s)]; count/=2*s; cout<<count<<endl; } return 0; } long long gcd(long long a,long long b) { long c; if(a==0) return b; while(b!=0) { c=b; b=a%b; a=c; } return a; }
上面的解法过于简洁,我直接用的模板解的,不过可以直接用上面的代码当做模板,真的很方便,下面我给出套用polya原理的公式的代码,这算正常思路,具体是如何运作Poj2409已经讲的很详细了。
#include<iostream> using namespace std; #include<cmath> int main() { int n; long long polya1(int n); while(cin>>n) { if(n==-1) break; if(n==0) { cout<<0<<endl; continue; } else cout<<polya1(n)<<endl; } return 0; } long long polya1(int n) { double x,m=n; long long t=0; int perm[100]; int polya(int *perm,int n,double &num); for(int i=0;i<=n-1;++i) { for(int j=0;j<=n-1;++j) perm[j]=(i+j)%n; polya(perm,n,x); t+=(pow(3.0,x)); } if(n%2==1) { for(int i=0;i<=n-1;++i) { for(int j=0;j<=n-1;++j) perm[(i+j)%n]=(i-j+n)%n; polya(perm,n,x); t+=(pow(3.0,x)); } } else { for(int i=0;i<=(n/2-1);++i) { for(int j=0;j<=n-1;++j) perm[(i+j)%n]=(i-j+n)%n; polya(perm,n,x); t+=(pow(3.0,x)); for(int j=0;j<=n-1;++j) perm[(i-j+n)%n]=(i+j+1)%n; polya(perm,n,x); t+=(pow(3.0,x)); } } t/=(2*n); return t; } int gcd(int a,int b) { int c; if(a==0) return b; while(b!=0) { c=b; b=a%b; a=c; } return a; } int polya(int *perm,int n,double &num) { int i,j,p,v[100]={0},ret=1; for(num=i=0;i<n;++i) if(!v[i]) { for(num++,j=0,p=i;!v[p=perm[p]];++j) v[p]=1; ret*=j/gcd(ret,j); } return ret; }