您的位置:首页 > 其它

Checker【解题报告】

2018-01-27 20:16 197 查看

Checker —AtCoder - 3876

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:

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 example above.

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


解析

啦啦啦,面对这道题我们首先要明白题意(就是因为题意理解错误,害我废了多少时间……):此题大概讲述的是,有一张无限大的’棋盘’,然后那张棋盘里包括了无数的k*k的小的方框,求一个原点,使得与规定的点的坐标尽量相同。

这道题,我们可以看出:它并不是一道算法题,那么,我们应该怎么思考呢?大体思路如下:

①我们可以看到,这道题的规模还是蛮大的,所以我们首先要做的是降维和移位,当然还有将字符转化为数字组成;

移位:

不难想到,其实移位就是平移:将每一个点的坐标%(2k),但是这不会影响结果吗?答案是不会的,因为*2k或%2k都仅仅是改变了它的位置,而没有改变它的颜色。




如此,我们便可以进行平移的行动,其次,是降维,这个将会在代码中体现。而将字符转化为数字,则单独标记处理即可。

②我们可以通过移动的方式来实现、找到到底有多少个点使我们所需要的。这可以分为两个部分:一是通过移动移动’x轴’(其实是平行于x轴)或’y轴’(其实是平行于y轴)上的线段来不断的’枚举‘(如上图的黄色部分)。二是通过平移’x轴’向上,一则减,一则加。

【代码实现】

#include<cstdio>
#include<cstring>
const int MAXN = 100000;
const int MAXK = 1000;
int x[MAXN + 5], y[MAXN + 5], c[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;
scanf("%d%d %c",&x[i],&y[i],&ch);
x[i] = x[i] % (2*K);//降维
y[i] = y[i] % (2*K);
if( ch == 'W' ) c[i] = 1;
else c[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 );
//printf("%d %d",p,q);
if( p ^ q == c[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];
}
}
printf("%d\n",Max);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: