您的位置:首页 > 其它

POJ 2409 Let it Bead【polya 计数法,burnside定理】

2011-02-16 16:23 701 查看
POJ 2409 Let it Bead

算法核心:polya 计数法,burnside定理
http://blog.sina.com.cn/s/blog_6f71bea30100opru.html

大意:

珠子的颜色有c种,问可组成多少种长度为s的项链?

分两种情况讨论:
旋转:
n种旋转方法每种旋转i个格(1<=i<=n)循环结有gcd(i,n)个
翻转:

(1)这种是经过某个顶点i与中心的连线为轴的翻转,由于n为偶数,有对称性,所以此种共n/2种翻转:

(2)这种是以顶点i和i+1的连线的中点与中心的连线为轴的翻转,同样,根据对称性,也有n/2种翻转:

所以给定长度n,共有2n种置换。

#include<stdio.h>
#include<string.h>
const int N = 35;
bool prime
;
void init()
{
int i,j;
memset(prime,true,sizeof(prime));
for(i=2;i<N;i++)
{
if(prime[i])
{
for(j=i+i;j<N;j+=i)
prime[j]=false;
}
}
}
int pow(int a,int b)
{
int ans = 1;
while(b--)ans=ans*a;
return ans;
}
int gcd(int a,int b)
{
int r;
if(a>b)
{
r=a;a=b;b=r;
}

while(a)
{
r=b%a;
b=a;
a=r;
}

return b;
}
int main()
{
int c,s;
init();
while(scanf("%d%d",&c,&s)!=EOF)
{
if(c==0&&s==0)break;
if(s==0||c==0)
{
printf("0\n");
continue;
}
int ans = 0;
if(prime[s])
{
ans = pow(c,s);
ans=ans+(s-1)*c;
}
else
{
ans = pow(c,s);
int i;
for(i=1;i<s;i++)
{
ans=ans+pow(c,gcd(i,s));
}
}

int cur = s;

if(s&1)//奇数
{
ans=ans+s*pow(c,s/2+1);
cur=cur+s;
}
else
{
ans=ans+s/2*pow(c,s/2)+s/2*pow(c,s/2+1);
cur=cur+s;
}

printf("%d\n",ans/cur);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: