HDU 4365——Palindrome graph——————【规律+快速幂】

Palindrome graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1727    Accepted Submission(s): 525


Problem Description
In addition fond of programing, Jack also loves painting. He likes to draw many interesting graphics on the paper.
One day,Jack found a new interesting graph called Palindrome graph. No matter how many times to flip or rotate 90 degrees, the palindrome graph are always unchanged.
Jack took a paper with n*n grid and K kinds of pigments.Some of the grid has been filled with color and can not be modified.Jack want to know:how many ways can he paint a palindrome graph?
 
Input
There are several test cases.
For each test case,there are three integer n m k(0<n<=10000,0<=m<=2000,0<k<=1000000), indicate n*n grid and k kinds of pigments.
Then follow m lines,for each line,there are 2 integer i,j.indicated that grid(i,j) (0<=i,j<n) has been filled with color.
You can suppose that jack have at least one way to paint a palindrome graph.
 
Output
For each case,print a integer in a line,indicate the number of ways jack can paint. The result can be very large, so print the result modulo 100 000 007.
 
Sample Input
3 0 2
4 2 3
1 1
3 1
 
Sample Output
8
3
 
Author
FZU
 
Source
 
 
题目大意:给出了回文图的定义,即前后翻转或者旋转90度不改变图的样子。给你n,m,k分别表示有n*n的格子图,有m个格子已经涂上颜色,现在有k种颜色用来涂满剩余的格子(其实并没有在题中读到这个意思,是看别人博客这么解释的),问有多少涂法。(其实题意感觉不是很清楚)。
 
解题思路:分析n*n的方格,我们只要分析出1/8的方格情况就行了。我们选择分析左上角上方的三角形,我们发现有1+2+3...+(n+1)/2个方格可能需要涂色。但是有m个方格已经涂了颜色,那么我们把所有可以通过转动能转到我们分析的三角形中的已涂色的格子的坐标化成在三角形中的坐标,可以先全化成左上角的大方格中,再化成上方的三角形中。对于涂色方案:k^x。k为给的涂料种数,x为左上角上方的三角形中可以任意涂色的格子个数(只要有部分格子在三角形中,该格子就算是在三角形中了)。
 
#include<bits/stdc++.h>
using namespace std;
const int mod=1e8+7;
typedef __int64 INT;
map<pair<int,int>,int>mp;
int Pow(INT x,int nn){
    INT ret=1;
    while(nn){
        if(nn&1)
            ret=ret*x%mod;
        x=x*x%mod;
        nn>>=1;
    }
    return ret;
}
int main(){
    int n,m,k,x,y;
    while(scanf("%d%d%d",&n,&m,&k)!=EOF){
        mp.clear();
        int pted=0,cnt=0;
        while(m--){
            scanf("%d%d",&x,&y);
            if(x>n-1-x){ //坐标转化成三角形中的对称坐标
                x=n-1-x;
            }
            if(y>n-1-y){
                y=n-1-y;
            }
            if(x>y){
                swap(x,y);
            }
            if(mp[make_pair(x,y)]==0){
                mp[make_pair(x,y)]=1;
                pted++;//已经涂过色的
            }
        }
        int cc=(n+1)/2; 
        cnt=(cc+1)*cc/2;    //三角形中的总格子数
        INT ans=Pow((INT)k,(cnt-pted));
        printf("%I64d
",ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/chengsheng/p/4774637.html