AcWing 95 费解的开关

前言

博客咕咕咕了很久了,是时候写一下了spa

题目连接

AcWing 95 费解的开关code

思路

首先能够看出ci

1.每个位置顶多只会操做一次。由于若是操做两次的话,至关于不操做,必然是不知足最优解
2.在一套方案中,操做的顺序可有可无。
3.若是咱们肯定了第I行的操做方案的话,那么后面的行数均可以依此递推,下面给出一个详细的解答。get

11011
10110
01111
11111
好比说这个例子,若是咱们肯定了第1行,那么第二行全部的0(坐标:a[i][j])
都只能是第三行a[i+1][j]来修改了,由于若是你第二行修改的话,那么第一行将会打乱,下面每一行依此类推。博客

而后再利用状态压缩,就能够了it

代码

#include <bits/stdc++.h>
using namespace std;
int n,m,i,j,k,a[7][7],ans1=1e6,b[7][7];
void read() {
    getchar();
    for (i=1; i<=5; i++) {
        for (j=1; j<=5; j++) {
            char ch=getchar();
            b[i][j]=ch-'0';
        }
        getchar();
    }
}
int main() {
    int n;
    cin>>n;
    while(n--) {
        read();
        for (i=0; i<=(1<<5); i++) {
            for (j=1; j<=5; j++) {
                for (k=1; k<=5; k++)
                    a[j][k]=b[j][k];
            }
            int ans=0;
            for (j=1; j<=5; j++)
                if (i>>(j-1) & 1) {
                    ans++;
                    a[1][j-1]^=1,a[1][j+1]^=1,a[1][j]^=1,a[2][j]^=1;
                }
            for (j=1; j<=4; j++)
                for (k=5; k>=1; k--)
                    if (!a[j][k]) {
                        ans++;
                        a[j][k]^=1,a[j+2][k]^=1,a[j+1][k]^=1,a[j+1][k+1]^=1,a[j+1][k-1]^=1;
                    }
            bool ok=true;
            for (j=1; j<=5; j++)
                for (k=1; k<=5; k++)
                    if (!a[j][k])
                        ok=false;
            if (ok)
                ans1=min(ans1,ans);
        }
        if (ans1>6)
            cout<<-1<<'\n';
        else
            cout<<ans1<<'\n';
        ans1=1e10;
    }
    return 0;
}
相关文章
相关标签/搜索