题意:给出两行等长数组,每个数代表着一个杠铃的重量,求最小要举起来杠铃的质量使相同质量的杠铃相邻(在一行相邻才行,上下两行的相邻不算),每行可放的杠铃数不限,且质量大的杠铃可以在同一行上滚动。
思路:(当求的答案是一个数的时候,一般由两种解法,一是直接模拟求出来,二就是二分枚举出来这个答案)当你发现这个答案很难通过模拟来操作出来结果的时候,那么就二分来判断当前值是否合适,即由答案来模拟是否可行。本题就是要通过二分来确定最小的重量
Hint:此外用数组一顶要注意范围,所以vector它不香么!!!,包括string的函数如果会用了简直太香了,vector必须要代替数组,string最好要会。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int a[maxn],b[maxn];
int ca[maxn],cb[maxn];
int n;
int check(int mid)
{
int cntm=0;
int cnt1=0;
for(int i=0;i<n;i++){
if(a[i]<=mid) ;
else ca[cnt1++]=a[i];
}
if(cnt1%2==1) return 0;
for(int i=0;i<cnt1/2;i++){
if(ca[2*i]!=ca[2*i+1]) return 0;
}
cnt1=0;
for(int i=0;i<n;i++){
if(b[i]<=mid) ;
else cb[cnt1++]=b[i];
}
if(cnt1%2==1) return 0;
for(int i=0;i<cnt1/2;i++){
if(cb[2*i]!=cb[2*i+1]) return 0;
}
return 1;
}
int main()
{
int maxx=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
maxx=max(maxx,a[i]);
}
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
maxx=max(maxx,b[i]);
}
int be=0;
int en=maxx;
int mid=(be+en)/2;
while(be<en){
mid=(be+en)/2;
if(check(mid)) {
en=mid;
}
else{
be=mid+1;
}
}
//以下三种输出都行
cout<<en<<endl;
//cout<<be<<endl;
//cout<<(en+be)/2<<endl;
return 0;
}