【数论】hdu5080 Colorful Toy (polya计数+简单几何)
来源:互联网 发布:手机和mac照片同步 编辑:程序博客网 时间:2024/05/22 05:07
题目大意:
给N个点,M条边,用C种颜色给点染色,其中图形旋转后相同的染色方案只算一种,求有多少种不同的染色方案。
解题思路:
涉及旋转,采用polya原理来解决问题。
因为给的点都是整数点,图形只有在旋转90‘,180‘,270‘时才可能与原图重合,旋转方案只有四种。
具体可以看代码。
关于polya原理 推荐论文
符文杰《Pólya原理及其应用》
http://wenku.baidu.com/link?url=VdNuq_v1vSljg1trqJLv-KqXApXxTXydSJVLw-Knq6Q4RLPJArpKTQJnJguA9jc7EPMbwk5jD8jVIJpDxap4KkDEMzXus0auGG6NUKAIbF7
polya原理的模板题:
poj1286
poj2409
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>using namespace std;#define MAXN 55#define MOD 1000000007#define EPS 1e-6typedef long long ll;struct node{ double x,y;} p[MAXN],tp[MAXN];int T,n,m,c;int M[MAXN][MAXN],tM[MAXN][MAXN],sp[MAXN];int cnt;double x,y;ll ans;ll mod_pow(ll a,ll b,ll p){ ll ans=1; a%=p; while(b) { if(b&1) ans=(ans*a)%p; a=(a*a)%p; b>>=1; } return ans;}void rotate(){ for(int i=0; i<n; i++)ans=ans*c%MOD; //不旋转 c^n for(int k=1; k<4; k++) //旋转k*90度 { int flag=1; memset(sp,0,sizeof(sp)); memset(tM,0,sizeof(tM)); //坐标转换 if(k==1)for(int i=0; i<n; i++)tp[i].x=-p[i].y,tp[i].y=p[i].x; else if(k==2)for(int i=0; i<n; i++)tp[i].x=-p[i].x,tp[i].y=-p[i].y; else if(k==3)for(int i=0; i<n; i++)tp[i].x=p[i].y,tp[i].y=-p[i].x; for(int i=0; i<n&&flag; i++) //判断旋转后点的坐标与原先点是否能一一对应 { int temp=0; for(int j=0; j<n&&!temp; j++) if(fabs(p[j].x-tp[i].x)<EPS&&fabs(p[j].y-tp[i].y)<EPS) temp=1,sp[j]=i;//旋转后点的映射 if(!temp)flag=0; } for(int i=0; i<n; i++) //求出旋转后点的关系矩阵 for(int j=0; j<n; j++) if(M[i][j])tM[sp[i]][sp[j]]=1; for(int i=0; i<n; i++) //判断两个关系矩阵是否相同 for(int j=0; j<n; j++) if(M[i][j]!=tM[i][j])flag=0; if(flag)//旋转后重合 { int res=0; for(int i=0; i<n; i++) //求循环节(polya) { if(sp[i]==-1)continue; int j=i; while(sp[j]!=i&&j!=-1) { int temp=j; j=sp[j],sp[temp]=-1; } sp[j]=-1;//查询到一个循环节 res++; } ll temp=1; for(int i=0; i<res; i++)temp=temp*c%MOD; //c^res ans=(ans+temp)%MOD; cnt++; } }}void init(){ for(int i=0; i<n; i++) { scanf("%lf%lf",&p[i].x,&p[i].y); x+=p[i].x,y+=p[i].y; } x/=n,y/=n; for(int i=0; i<n; i++)p[i].x-=x,p[i].y-=y; //将图平移使得中心点是原点 for(int i=1; i<=m; i++) { int a,b; scanf("%d%d",&a,&b); a--,b--; M[a][b]=M[b][a]=1; }}int main(){ // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&c); memset(M,0,sizeof(M)); init(); x=y=0; cnt=ans=1; rotate(); ans=ans*mod_pow(cnt,MOD-2,MOD)%MOD;//相当于除以n //pow_MOD(a , b , MOD) 当MOD是素数时且b远大于MOD 那么 pow_MOD(a, b,MOD ) = pow_MOD(a , b%(MOD-1),MOD); cout<<ans<<endl; } return 0;}
0 0
- 【数论】hdu5080 Colorful Toy (polya计数+简单几何)
- 2014鞍山区域赛(简单几何+polya)HDU5080
- HDU5080-Colorful Toy-2014鞍山K题-polay计数
- hdu 5080 - Colorful Toy(2014 AnShan)几何+polya
- HDU 5080 Colorful Toy(polya+计算几何)
- HDU5088 Colorful Toy(计算几何+ploya计数)
- HDU 5080 Colorful Toy (polya定理)
- HDU 3629 Convex(数论+计数+几何)
- HDU 2481 Toy(08成都现场 Polya,递推,矩阵,数论……)
- poj 题目2398 Toy Storage (简单计算几何)
- Colorful Rainbows(计算几何)
- Polya计数
- Polya计数
- AtCoder:Colorful Balls(思维 & 数论)
- POJ2318 TOYS 和POJ2398 Toy Storage题解(点在四边形内)(简单几何)
- Uva 10601 Cubes(polya计数)
- poj 2398 Toy Storage(计算几何)
- Toy Storage(二维计算几何基础)
- 关于LeetCode中Remove Element一题的理解
- Maven 构建多模块(8)
- 腾讯校招模拟面试题之蛇形打印
- hdu1875——畅通工程再续(最小生成树)
- 关于点9图的制作(每天积累一点点)
- 【数论】hdu5080 Colorful Toy (polya计数+简单几何)
- 数论 快速矩阵幂 POJ 3070 Fibonacci
- 简单dp
- 【华为OJ】超长正整数相加
- LightOJ 1197 Help Hanzo 求区间内素数的个数
- Kafka常用命令
- [ASP.NET MVC 小牛之路]02 - C#知识点提要
- 最大子段积
- 向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读