[题解]CF1926F Vlad and Avoiding X

非常(断句)好暴力。。。

题意

有一个 7×7 个网格,每一个格子上都有两种颜色,一种是 B,一种是 W

现在你可以让一个格子上的颜色经行反转(即 B 变为 WW 变为 B),使得网格上没有一个 X 形的图形的颜色都是 B

思路

首先通过瞪眼法可以发现答案最多为 8

然后你再按照下图重新分析一下,发现蓝色和红色的反转是无关的,并且红色和蓝色反转的次数都最多为 4,因此考虑分别计算。

以下以红色为例,蓝色的计算方式同理。

首先枚举反转次数 i,然后暴力 DFS 去 check。由于我们将红色和蓝色分开了,因此红色点集合的元素是 n2 的。

单次 check 的复杂度就是在红色的 n2 选出 i 个数去反转,因此为 Θ((25i)×n2)。总复杂度大约是 Θ((254)×n)

Code

#include <bits/stdc++.h>
#define re register

using namespace std;

const int N = 10;
int dx[] = {0,1,1,-1,-1};
int dy[] = {0,1,-1,1,-1};
int arr[N][N];
char s[N][N];

struct point{
    int x,y;
};
vector<point> g[2];

inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 3) + (r << 1) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}

inline void init(){
    for (re int i = 1;i <= 7;i++){
        for (re int j = 1;j <= 7;j++) g[(i + j) % 2].push_back({i,j});
    }
}

inline bool check(int op){
    for (auto x:g[op]){
        if (!arr[x.x][x.y]) continue;
        int num = 0;
        for (re int i = 1;i <= 4;i++){
            int tx = x.x + dx[i];
            int ty = x.y + dy[i];
            if (tx >= 1 && tx <= 7 && ty >= 1 && ty <= 7) num += arr[tx][ty];
        }
        if (num == 4) return false;
    }
    return true;
}

inline bool dfs(int u,int res,int op){
    if (!res) return check(op);
    if (u == g[op].size()) return false;
    bool ok = false;
    point x = g[op][u];
    ok |= dfs(u + 1,res,op);
    arr[x.x][x.y] ^= 1;
    ok |= dfs(u + 1,res - 1,op);
    arr[x.x][x.y] ^= 1;
    return ok;
}

inline void solve(){
    int ans = 0;
    for (re int i = 1;i <= 7;i++){
        scanf("%s",s[i] + 1);
        for (re int j = 1;j <= 7;j++) arr[i][j] = (s[i][j] == 'B');
    }
    for (re int i = 0;i <= 4;i++){
        if (dfs(0,i,0)){
            ans += i;
            break;
        }
    }
    for (re int i = 0;i <= 4;i++){
        if (dfs(0,i,1)){
            ans += i;
            break;
        }
    }
    printf("%d\n",ans);
}

int main(){
    init();
    int T;
    T = read();
    while (T--) solve();
    return 0;
}

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18266734

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示