这题给一个n*n的正方形涂色,使之成为又中心对称又轴对称的图形。
给出了m点已经涂色,会告诉你他们的坐标。 再告诉你用k种颜色涂。
不考虑已经涂色的情况:
这题是一圈一圈地考虑,对于每个圈,只考虑一条边的一半,即(n + 1) >> 1; 对于每一圈都如此。 那么总的可以由k种颜色中任意涂的个数total是1 + 2 + 3 + …… + (1 + n) >> 1;
考虑已经涂色的:
那么就在total里面减去已经涂色的。
重点在于去重。
对于每一圈来说,将应该涂相同颜色的位置映射到一个位置。
对于map,我只能说无能为力。 比如,先插入(1,2)、再插入(1,3)。 对于MAP.insert( make_pair<int,int>(x,y) ), 人家输出的是(1,2)。也就是他插不进去(1,3); 对于MAP[x] = y, 人家输出的是(1,3)。也就是他把原来给覆盖了。
所以这里用的是手动版。
还有一个地方不解的是,对于去重,离中心点相同距离的点应该都为同一种颜色。所以,我将m个坐标离中心点的距离放在一个为double型的数组里面,WA了。不解。
以下是AC代码:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #define f(x) ((x)>nn?n-(x)+1:(x)); using namespace std; const __int64 M=100000007; typedef __int64 LL; long long fun(long long a,long long n,long long p) { long long ret=1; long long A=a; while(n) { if (n & 1) ret=(ret*A)%p; A=(A*A)%p; n>>=1; } return ret; } struct loca{ int x;int y; bool operator < (const loca& cmp) const{ if(x == cmp.x) return y < cmp.y; return x < cmp.x; } }point[2100]; int main(){ LL n,m,k,x,y,nn,sub,t; while(scanf("%I64d %I64d %I64d",&n,&m,&k)!=EOF){ sub = 0; nn = (n + 1) >> 1; for(int i=0;i<m;i++) { scanf("%I64d%I64d",&x,&y); x++,y++; x = f(x); y = f(y); if(x > y) swap(x,y); point[sub].x = x; point[sub ++].y = y; // MAP.insert( make_pair<int,int>(x,y) ); // MAP[x] = y; } sort(point,point + sub); if(m){ t = 1; //刚开始就有一个 for(int i = 1; i < sub; i ++) if(point[i].x != point[i - 1].x || point[i].y != point[i - 1].y) t ++; } else t = 0; t = (nn + 1) * nn / 2 - t; printf("%I64d\n",fun(k,t,M)); } return 0; }