棋子染色问题(burnside引理或者polya定理)

最近笔试的时候遇到一个问题,题目是:用两种颜色去染排成一个圈的8个棋子,如果可以通过旋转得到则只算一种,问一共有多少种染色方式 ?

当时因为时间的关系,没有做出来,后来仔细考虑了一下,这是组合数学的题目。
重新回顾了下,组合数学老师上课的PPT,果然有这类题目。
让我们一起先理解下面两个题目吧。
棋子染色问题(burnside引理或者polya定理)_第1张图片

棋子染色问题(burnside引理或者polya定理)_第2张图片

棋子染色问题(burnside引理或者polya定理)_第3张图片

棋子染色问题(burnside引理或者polya定理)_第4张图片

而NYOJ也有一道很类似的题目。
NYOJ 280:一盒有红、蓝、绿三种颜色的珠子,每种颜色珠子的个数都大于24,现在LK想用这一盒珠子穿出一条项链,项链上的珠子个数为n(0<=n<=24),请你帮她计算一下一共可以用这一盒珠子可以穿出多少条不同的项链。通过旋转、翻转达到同一种状态的被认为是相同的项链。

解答思路可以参考:http://blog.csdn.net/u013050857/article/details/43833353

而我们这个题目相比之下,就只有旋转,没有翻转操作了。
主要利用GCD求出每次顺时间旋转1~N个棋子的循环节数就OK。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int gcd(int a,int b){
    while(a%b){
        int t=a;
        a=b;
        b=t%b;
    }
    return b;
}

int main()
{
    int n,m;
    cin>>n>>m;
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=pow(m,gcd(n,i));
    }
    printf("%d\n",sum/n);
    return 0;
}

写出代码,输入 8 2
求得的36即为答案。

你可能感兴趣的:(棋子染色问题(burnside引理或者polya定理))