您的位置:首页 > 其它

Plóya定理 的应用

2010-10-25 11:41 281 查看
问题:对于一个n的正方形连成环,用m种颜色染色,可得到多少种不重复的不同的图像?经过旋转可以重合的染色方案视为一种。

1.对于有c种颜色,s个珠子的旋转为重复的种类一共有ans种。

算法代码如下:

for(i=1;i<=s;i++)
{
ans+=(__int64)(pow((double)c,(int)gcd(s,i)));
}
printf("旋转:%I64d ",ans/s);


2.对于要考虑翻转与旋转的那么分析如下:

翻转 (这个要分奇偶)

奇数:
只能对称轴穿过某颗珠子,循环个数为(n+1)/2,共有n个这样的循环群;

偶数:
对称轴过两个珠子,循环个数(n+2)/2,共有n/2个这样的循环群;
对称轴过两个相邻珠子的,循环个数n/2,共有n/2个这样的循环群。

对于有c种颜色,s个珠子的翻转为重复的种类一共有ans种。
if(s&1)   //为奇数时
{
ans+=(__int64)(pow((double)c,(int)(s+1)/2)*s);
}
else        //为偶数时
{
ans+=(__int64)(pow((double)c,(int)s/2)*(s/2))		ans+=(__int64)(pow((double)c,(int)(s+2)/2)*(s/2));
}
printf("翻转:%I64d  ",ans/2);

综合考虑如下:
对于c种颜色,s种珠子,要考虑旋转与翻转的情况如下,有ans种方案(AC代码如下)
http://poj.org/problem?id=2409
//Plóya定理的应用,要记得考虑是否要考虑旋转或者翻转等问题
#include<stdio.h>
#include<math.h>
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
int main()
{
//	freopen("in.txt","r",stdin);
int c, s, i;
__int64 ans,t;
while(scanf("%d%d",&c,&s))
{
if(c==0 && s==0)
break;
ans = 0;
for(i=1; i<=s; i++)//考虑旋转的情况
{
ans += (__int64)pow(double(c),(int)gcd(s,i));
}
//printf("旋转的情况:%d/n",ans/s);
//	t=ans;
//考虑翻转的情况
if(s&1)//珠子数为奇数
{
ans += (__int64)pow(double(c),(int)((s+1)/2))*s;
}
else
{
ans += (__int64)pow(double(c),(int)(s/2))*(s/2);
ans += (__int64)pow(double(c),(int)((s+2)/2))*(s/2);
}

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