Comet OJ - Contest #3 B -棋盘 (思维+分类讨论)
阅读原文时间:2023年07月11日阅读:4

题目描述

小猫有一个 2\times N2×N 的棋盘,每一个格子放着一个黑棋子或白棋子。

小熊觉得小猫的棋盘不够好看,想要把棋盘上的一部分白棋子替换成黑棋子,使得所有黑棋子都能够在仅允许上下左右四个方向走,且仅经过黑棋子在的格子的情况下两两互相到达。

小熊想知道至少要将多少个白棋子替换成黑棋子。

注意:不能将黑棋子替换成白棋子。

输入描述

第一行有一个正整数 NN (1 \le N \le 10^51≤N≤105)。

接下来两行,每行 NN 个整数,描述整个棋盘。若第 ii 行的第 jj 个整数是 00,代表棋盘 (i,j)(i,j) 的位置放着白棋子,若是 11 则放着黑棋子。

数据保证至少存在一个黑棋子。

输出描述

输出一行包含一个整数,表示答案。

样例输入 1

3
1 0 0
0 0 1

样例输出 1

2

样例输入 2

5
0 1 0 1 0
0 0 1 0 0

样例输出 2

1

提示

样例一中可以将第一行的两个白棋子替换成黑棋子。

样例二中可以将位置 (1, 3)(1,3) 的白棋子换成黑棋子。

思路:

由于题目说这个矩阵只有两行,我们知道,对于每一列,2块方格,有4个组合方式,

有1的列,只有以下三个方式是可能需要变化前面的白棋子的。

分别是:

两个1

上0下1

上1下0

如果是两个1,我们可以从上一个有1的位置,直线连接过来到当前的一个1,记上一个1出来的位置是last

则对答案的贡献是 i-last-1

如果上1下0,我们需要根据last位置的1是什么情况,。如果上行有1,那么贡献是  i-last-1 否则是 i-last

上0下1 和上面一样来处理即可。

每遇到一列有1就去维护 last 和 1在上还是在下的信息Pos

细节见代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i
#define pll pair
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=;while(b){if(b%)ans=ans*a%MOD;a=a*a%MOD;b/=;}return ans;}
inline void getInt(int* p);
const int maxn=;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int a[maxn][];
int n;
int main()
{

//freopen("D:\\\\common\_text\\\\code\_stream\\\\in.txt","r",stdin);  
//freopen("D:\\\\common\_text\\\\code\_stream\\\\out.txt","w",stdout);  
gbtb;  
cin>>n;  
int r=-;  
int l=inf;  
repd(j,,)  
repd(i,,n)  
{  
    cin>>a\[i\]\[j\];  
    if(a\[i\]\[j\])  
    {  
        r=max(r,i);  
        l=min(l,i);  
    }  
}  
int last=l;  
int pos;  
if(a\[l\]\[\]==a\[l\]\[\])  
{  
    pos=;  
}else if(a\[l\]\[\])  
{  
    pos=;  
}else  
{  
    pos=;  
}  
int ans=;  
// cout<<l<<" "<<r<<endl;  
repd(i,l+,r)  
{  
    if(a\[i\]\[\]||a\[i\]\[\])  
    {  
        if(a\[i\]\[\]==a\[i\]\[\])  
        {  
            pos=;  
            ans+=i-last-;  
        }else if(a\[i\]\[\])  
        {  
            if(pos==)  
            {  
                pos=;  
                ans+=i-last-;  
            }else if(pos==)  
            {  
                pos=;  
                ans+=i-last;  
            }else  
            {  
                pos=;  
                ans+=i-last-;  
            }  
        }else if(a\[i\]\[\])  
        {  

// db(pos);
if(pos==)
{
pos=;
ans+=i-last-;
}else if(pos==)
{
// db(last);
ans+=i-last;
pos=;
}else
{
pos=;
ans+=i-last-;
}
}
last=i;
}
}
cout<<ans<<endl;
return ;
}

inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '');
while ((ch = getchar()) >= '' && ch <= '') { *p = *p * - ch + ''; } } else { *p = ch - ''; while ((ch = getchar()) >= '' && ch <= '') {
*p = *p * + ch - '';
}
}
}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器