AtCoder086--Checker(黑白格子)
Problem Statement
AtCoDeer is thinking of painting an infinite two-dimensional grid in a checked pattern of side K. Here, a checked pattern of side K is a pattern where each square is painted black or white so that each connected component of each color is a K × K square. Below is an example of a checked pattern of side 3:
AtCoDeer has N desires. The i-th desire is represented by xi, yi and ci. If ci is B, it means that he wants to paint the square (xi,yi) black; if ci is W, he wants to paint the square (xi,yi) white. At most how many desires can he satisfy at the same time?Constraints
- 1 ≤ N ≤ 105
1 ≤ K ≤ 1000
0 ≤ xi ≤ 109
0 ≤ yi ≤ 109
If i ≠ j, then (xi,yi) ≠ (xj,yj).
ci is B or W.
N, K, xi and yi are integers. - Input
Input is given from Standard Input in the following format:
Input is given from Standard Input in the following format:
N K
x1 y1 c1
x2 y2 c2
.
.
xN yN cN
- Output
Print the maximum number of desires that can be satisfied at the same time.
- Sample Input 1
4 3
0 1 W
1 2 W
5 3 B
5 4 B
- Sample Output 1
4
He can satisfy all his desires by painting as shown in the exampleabove.
Sample Input 2
2 1000
0 0 B
0 1 W
- Sample Output 2
2
- Sample Input 3
6 2
1 2 B
2 1 W
2 2 B
1 0 B
0 6 W
4 5 W
Sample Output 3
4
题目大意
AtCoDeer要check一个无穷无尽的网格,网格中黑白交错着分布着一些k*k的黑白正方块,每行输入是“xi yi ci .”,表示AtCoDeer想要(xi,yi)的颜色为ci,其中“B”代表黑色,”W”代表白色。
求AtCoDeer可以同时满足哪些愿望。
(只是大意,非标准翻译)
思路解析
由于n是无穷无尽的,所以我们可以把输入的所有格子都可以通过取模压缩在一个2k*2k的网格中(2k是因为黑白两色的格子交错着的)
然后在那个2k*2k的格子里枚举长度为k的横竖边
就像这样:(示例为k=4)
通过异或运算,被两条边都覆盖了的和都没被覆盖是一个颜色,其它的格子是另一个颜色。
如果我们设定的颜色和AtCoDeer想要的颜色一致的话,就可以实现(我们可以先假定这个颜色,因为反正是非黑即白的关系,在cnt和N-cnt中选一个大的)
代码实现
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 100000
#define MAXK 1000
int x[MAXN+5],y[MAXN+5],m[MAXN+5];
int y1[10*MAXK+5];
int main()
{
int N,K,Max=0,cnt=0;
scanf("%d %d",&N,&K);
for(int i=1;i<=N;i++)
{
char ch[25];
scanf("%d %d %s",&x[i],&y[i],ch);
x[i]=x[i]%(2*K);
y[i]=y[i]%(2*K);
if(ch[0]=='W') m[i]=1;
else m[i]=0;
}
for(int i=0;i<=K;i++)
{
cnt=0;
memset(y1,0,sizeof(y1));
for(int j=1;j<=N;j++)
{
int p=(i<=x[j]&&x[j]<i+K);
int q=(0<=y[j]&&y[j]<K);
if(p ^ q==m[j])
{
cnt++;
y1[y[j]]++;
}
else
y1[y[j]]--;
}
for(int j=0;j<=K;j++)
{
if(cnt>Max)Max=cnt;
if(N-cnt>Max) Max=N-cnt;
if(j!=K)
cnt=cnt-y1[j]-y1[K+j];
}//y1[]表示这一行有多少满足情况的
}
printf("%d\n",Max);
}