题意:一个 n*n的 矩阵 ,有m个 格子,已经染色,有 k种颜色可以选 ,,对剩下的格子进行染色,使得 矩阵无论 反转 或者 旋转 90 度 多少次 都不变,
一开思做这道题是,找到了 规律,以为可以 用bool 类型 存 5000*5000 的数组,但每一次 ,都要初始划,带来了很大的时间消耗,直接 tle 。。。。。。
其实 可以 有结构体 来存每次将 坐标 缩小在 左上角的 下三角 内,然后 排序 ,判断 有多少 不同的即可
规律:
因为满足左右上下 左右对称 ,对角线对称,所以 我们 只要 算 左下角的 下三角就可以了
左上角 下三角的方格数 - 染了色的方格数对于n*n的方格纸,在格子里填颜色,要满足任意水平、垂直翻转后看到的图形都一样,则可填 (n/2+1)*(n/2)/2 种颜色。
有些方格已经填了颜色,对于已填色的方格,会固定对应格子的颜色,使得可填颜色数减1.注意多个已填色格本来就是同色格,不要多减
因n范围比较大,不能直接开数组,用map记录即可
最后,填色方法数为 可用颜色种类k^可填颜色数,用下快
1 #include<stdio.h>
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cmath>
6 #include<queue>
7 #include<set>
8 #include<map>
9 #define Min(a,b) a>b?b:a
10 #define Max(a,b) a>b?a:b
11 #define CL(a,num) memset(a,num,sizeof(a));
12 #define inf 9999999
13 #define maxn 5010
14 #define mod 100000007
15 #define eps 1e-6
16 #define ll long long
17 using namespace std;
18
19 map<pair<int ,int>,int>mat;
20 ll n,m,k,sum;
21 ll pow_mod(ll a,ll n,ll m){
22 int b = 1;
23 while(n>0){
24 if(n&1)b = (b*a)%m;
25 n>>=1;
26 a = (a*a)%m;
27 }
28 return b;
29 }
30 int main()
31 {
32 int i,x,y,j;
33 while(scanf("%lld %lld %lld",&n,&m,&k)!=EOF)
34 {
35 mat.clear();
36 sum = 0;
37 for( i = 0; i < m;++i)
38 {
39 scanf("%d %d",&x,&y);
40
41 if(x > n - x - 1) x = n - x -1;
42 if(y > n - y - 1) y = n - y - 1;
43 if(x < y)
44 {
45 int t = x;
46 x = y;
47 y = t;
48
49 }
50 if(!mat[make_pair(x,y)])
51 {
52 mat[make_pair(x,y)] = 1 ;
53 sum ++ ;
54 }
55
56 }
57
58
59 ll cnt = (n + 1) /2;
60
61 ll ans = pow_mod(k,cnt*(cnt + 1)/2 - sum ,mod);
62
63 printf("%lld\n",ans);
64
65
66
67 }
68 }
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cmath>
6 #include<queue>
7 #include<set>
8 #include<map>
9 #define Min(a,b) a>b?b:a
10 #define Max(a,b) a>b?a:b
11 #define CL(a,num) memset(a,num,sizeof(a));
12 #define inf 9999999
13 #define maxn 5010
14 #define mod 100000007
15 #define eps 1e-6
16 #define ll long long
17 using namespace std;
18
19 map<pair<int ,int>,int>mat;
20 ll n,m,k,sum;
21 ll pow_mod(ll a,ll n,ll m){
22 int b = 1;
23 while(n>0){
24 if(n&1)b = (b*a)%m;
25 n>>=1;
26 a = (a*a)%m;
27 }
28 return b;
29 }
30 int main()
31 {
32 int i,x,y,j;
33 while(scanf("%lld %lld %lld",&n,&m,&k)!=EOF)
34 {
35 mat.clear();
36 sum = 0;
37 for( i = 0; i < m;++i)
38 {
39 scanf("%d %d",&x,&y);
40
41 if(x > n - x - 1) x = n - x -1;
42 if(y > n - y - 1) y = n - y - 1;
43 if(x < y)
44 {
45 int t = x;
46 x = y;
47 y = t;
48
49 }
50 if(!mat[make_pair(x,y)])
51 {
52 mat[make_pair(x,y)] = 1 ;
53 sum ++ ;
54 }
55
56 }
57
58
59 ll cnt = (n + 1) /2;
60
61 ll ans = pow_mod(k,cnt*(cnt + 1)/2 - sum ,mod);
62
63 printf("%lld\n",ans);
64
65
66
67 }
68 }