写这道题的时候很久没想出来,立即求助于我的大佬朋友 行码棋
,大佬给出解答,十分感谢
他的题解入口:链接
本题为软院招新赛题目,用内网才能看到
题目链接
奕星的棋盘
描述
若世有神明 亦会胜他半子–奕星
奕星有一个 2 × N 2×N 2×N 的棋盘,奕星觉得自己的棋盘不够好看,想要把棋盘上的一部分白棋子替换成黑棋子,使得所有黑色棋子之间都可以联通,其中两个棋子斜着摆放不算是相连。
奕星想知道至少要将多少个白棋子替换成黑棋子。
注意:不能将黑棋子替换成白棋子。
输入
第一行有一个正整数 N
,(1<= N <=10^5)
(1≤N≤10^5)
接下来两行,每行 N
个整数,描述整个棋盘。若第 i
行的第 j
个整数是 0
,代表棋盘 (i,j)
的位置放着白棋子,若是 1
则放着黑棋子。
数据保证至少存在一个黑棋子
输出
输出一行包含一个整数,表示答案。
样例一:
输入
5
0 1 0 1 0
0 0 1 0 0
输出
1
样例二
输入
3
1 0 0
0 0 1
输出
2
本题思路来源于我的好朋友
算法 枚举+思维+贪心
本题可画分为四种情况,x为任意数
1.
0 x
0 x
1 x
0 x
0 x
1 x
1 x
1 x
详细讲解看文章首处链接,十分详细
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
const int mod=1e9+7;
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int x;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x)
{
if(a[i])a[i]=3;
else a[i]=2;
}
}
LL res=0;
for(int i=1,j=-1;i<=n;i++)
{
if(a[i])
{
if(j!=-1)
{
if(a[i]==3||a[j]==3)res+=i-j-1;
else if(a[i]==a[j])res+=i-j-1;
else res+=i-j,a[i]=3;
}
j=i;
}
}
cout<<res<<endl;
}