码迷,mamicode.com
首页 > 其他好文 > 详细

[codevs 2926] 黑白瓷砖(2002年安徽省队选拔赛)

时间:2015-02-10 00:39:22      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:polya定理   置换群   

描述

http://codevs.cn/problem/2926/


题解:

Polya定理的应用。
由于第一次做polya定理的题,故要写的详细些。
首先可以从题目中读到三个置换以及一个不动置换:

  1. 顺时针旋转120度。
  2. 顺时针旋转240度。
  3. 左右翻转180度。
  4. 旋转0度。(不动置换)

开始我本以为这样就算完成任务,就拿polya定理演算了一遍,结果发现n=2,n=3都不对。后来才明白现在的置换群中不满足封闭性。比如先顺时针旋转再左右翻转后的图形就不包含在内。所以还要增加两个斜向的翻转。

现在可以统计每个置换中循环的个数了:

  1. 旋转操作,可以画图数学归纳一下,每个循环中都有3个元素,(因为120度是360度的三分之一),那么一共就有((点数+2)/ 3)个循环。设为x。
  2. 翻转操作,经归纳,中轴线上有(n+1)/ 2 个点,每个点单独构成一个循环,其余两两配对,所以这些单点少算了一次,总循环数即 (总点数+中轴线上的点数)/ 2。设为y。
  3. 不动置换,即总点数。设为z。

接下来根据polya定理求最终结果。因为旋转有两个置换,翻转有三个(左右、斜向两个),还有一个不动置换,所以最后结果是

ans=2?2x+3?2y+2z6


代码:

其实需要高精,但我没打。

#include<cstdio>
using namespace std;

int main() 
{
    int n;
    scanf("%d", &n); //底层点数 
    int s = n * (n + 1) / 2; //总点数 
    int m = (s + (n + 1) / 2) / 2; //一个翻转置换的循环数 
    printf("%d\n", (2*(1<<((s+2)/3)) + 3*(1<<m) + (1<<s)) / 6);
    return 0;
}

[codevs 2926] 黑白瓷砖(2002年安徽省队选拔赛)

标签:polya定理   置换群   

原文地址:http://blog.csdn.net/qq_21110267/article/details/43676445

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!