AtCoder Regular Contest 089 D – Checker 思维题、点的转移、二维前缀和

ProLightsfx 2018-2-1 190 2/1

D - Checker 思维题、点的转移、二维前缀和

My Solution

题意:用k*k的黑白正方形交替填充二维坐标平面如上图,现给出n个方案(x, y, color表示坐标(x,y)的颜色为color),问最多有多少方案能够同时满足。

思维题、点的转移、二维前缀和

首先要想到把所有的点转移到平面{(0,0)~(k-1,k-1)}内。

1、按照45度向量移动不会改变颜色,

modx = x / k, mody = y / k;  x -= min(modx, mody) * k; y -= min(modx, mody) * k;

2、跳动2*k格也不会改变颜色,所以接下来

if(modx > mody) x -= (modx - mody) / 2 * 2 * k; else y -= (mody - modx) / 2 * 2 * k;

3、最后跳动k个需要改变颜色,所以

if(ch == 'W'){
    if(x / k) b[x % k][y]++;
    else if(y / k) b[x][y % k]++;
    else w[x][y]++;
}
else{
    if(x / k) w[x % k][y]++;
    else if(y / k) w[x][y % k]++;
    else b[x][y]++;
}

按照这3个步骤就可以把坐标平面上所以数据的点都转移到平面{(0,0)~(k-1,k-1)}内。

接下来要确定这个平面颜色的分配,可以用一个“十”字来划分区域。

{(0,0)~(i,j)}和{(i+1,j+1)~(k-1,k-1)}为白色,

{(0,j+1)~(i,k-1)}和{(i+1,0)~(k-1,j)}为黑色。

或者

{(0,0)~(i,j)}和{(i+1,j+1)~(k-1,k-1)}为白色,

{(0,j+1)~(i,k-1)}和{(i+1,0)~(k-1,j)}为黑色。

所以需要快速的获取一个矩形区域的数值之和,可以用二维前缀和来表示。

遍历{(0,0)~(k-1,k-1)}内所有的点,

ansb = sumb[i][j] + sumw[k-1][j] - sumw[i][j] + sumw[i][k-1] - sumw[i][j] + sumb[k-1][k-1] - sumb[i][k-1] - sumb[k-1][j] + sumb[i][j];
answ = sumw[i][j] + sumb[k-1][j] - sumb[i][j] + sumb[i][k-1] - sumb[i][j] + sumw[k-1][k-1] - sumw[i][k-1] - sumw[k-1][j] + sumw[i][j];
即可得出答案,ans = max(ans, max(ansb, answ));

时间复杂度 O(K*K)

空间复杂度 O(K*K)

#include 
#include 
 
using namespace std;
typedef long long LL;
const int MAXN = 1e3 + 8;
 
int b[MAXN][MAXN], w[MAXN][MAXN], sumb[MAXN][MAXN], sumw[MAXN][MAXN];
 
int main()
{
    #ifdef LOCAL
    freopen("b.txt", "r", stdin);
    //freopen("b.out", "w", stdout);
    int T = 1;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);
 
    int n, k, i, j, x, y, modx, mody, ansb, answ;
    char ch;
    cin >> n >> k;
    for(i = 0; i < n; i++){ cin >> x >> y >> ch;
        modx = x / k, mody = y / k;
        x -= min(modx, mody) * k;
        y -= min(modx, mody) * k;
        if(modx > mody){
            x -= (modx - mody) / 2 * 2 * k;
        }
        else{
            y -= (mody - modx) / 2 * 2 * k;
        }
        //cout << x << " " << y <<" " << ch << endl;
        if(ch == 'W'){
            if(x / k) b[x % k][y]++;
            else if(y / k) b[x][y % k]++;
            else w[x][y]++;
        }
        else{
            if(x / k) w[x % k][y]++;
            else if(y / k) w[x][y % k]++;
            else b[x][y]++;
        }
    }
    for(i = 0; i < k; i++){
        for(j = 0; j < k; j++){
            if(i == 0){
                if(j == 0){
                    sumb[i][j] = b[i][j];
                    sumw[i][j] = w[i][j];
                }
                else{
                    sumb[i][j] =  sumb[i][j-1] + b[i][j];
                    sumw[i][j] =  sumw[i][j-1] + w[i][j];
                }
            }
            else{
                if(j == 0){
                    sumb[i][j] =  sumb[i-1][j] + b[i][j];
                    sumw[i][j] =  sumw[i-1][j] + w[i][j];
                }
                else{
                    sumb[i][j] =  sumb[i-1][j] + sumb[i][j-1] + b[i][j] - sumb[i-1][j-1];
                    sumw[i][j] =  sumw[i-1][j] + sumw[i][j-1] + w[i][j] - sumw[i-1][j-1];
                }
            }
 
        }
    }
    //cout << k << endl;
    int ans = 0;
    for(i = 0; i < k; i++){
        for(j = 0; j < k; j++){
           // cout << ans << " " << sumb[i][j] + sumw[k-1][k-1] - sumw[i][j] << " " << sumw[i][j] + sumb[k-1][k-1] - sumb[i][j] << endl;
            ansb = sumb[i][j] + sumw[k-1][j] - sumw[i][j] + sumw[i][k-1] - sumw[i][j] + sumb[k-1][k-1] - sumb[i][k-1] - sumb[k-1][j] + sumb[i][j];
            answ = sumw[i][j] + sumb[k-1][j] - sumb[i][j] + sumb[i][k-1] - sumb[i][j] + sumw[k-1][k-1] - sumw[i][k-1] - sumw[k-1][j] + sumw[i][j];
            ans = max(ans, max(ansb, answ));
        }
    }
    cout << ans << endl;
 
 
    #ifdef LOCAL
    cout << endl;
    }
    #endif // LOCAL
    return 0;
}
 

 

问题Source

AtCoder Regular Contest 089

 

Thank you!

                                                                                                                                             ------from ProLightsfx

 

- THE END -

ProLightsfx

11月17日01:13

最后修改:2024年11月17日
0

非特殊说明,本博所有文章均为博主原创,未经许可不得转载。

共有 0 条评论