这题给一个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;
}