P7305 [COCI2018-2019#1] Cipele 题解
题目传送门
很显然这题答案有单调性,于是考虑二分。
二分答案(求最小值)模板:
while(l < r)
{
int mid = (l + r) / 2;
if(check(mid))r = mid;
else l = mid + 1;
}
cout << r;
其中,check 函数就是判断条件。怎么判断呢?显然随意匹配肯定不行,于是考虑排序。这样,如果第
bool check(int mi)
{
int cn = 0,un = 0;
if(n < m)
{
for(int i = 1;i <= n;i ++)
for(int j = cn + 1;j <= m;j ++)
if(abs(a[i] - b[j]) <= mi)
{
un ++;
cn = j;
break;
}
}
else
{
for(int i = 1;i <= m;i ++)
for(int j = cn + 1;j <= n;j ++)
if(abs(b[i] - a[j]) <= mi)
{
un ++;
cn = j;
break;
}
}
return un >= min(n,m);
}
AC code:
#include <iostream>
#include <algorithm>
using namespace std;
long long n,m,a[1000005],b[1000005],l,r = 1e10;
bool check(int mi)
{
int cn = 0,un = 0;
if(n < m)
{
for(int i = 1;i <= n;i ++)
for(int j = cn + 1;j <= m;j ++)
if(abs(a[i] - b[j]) <= mi)
{
un ++;
cn = j;
break;
}
}
else
{
for(int i = 1;i <= m;i ++)
for(int j = cn + 1;j <= n;j ++)
if(abs(b[i] - a[j]) <= mi)
{
un ++;
cn = j;
break;
}
}
return un >= min(n,m);
}
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)cin >> a[i];
for(int i = 1;i <= m;i ++)cin >> b[i];
sort(a + 1,a + n + 1);
sort(b + 1,b + m + 1);
while(l < r)
{
int mid = (l + r) / 2;
if(check(mid))r = mid;
else l = mid + 1;
}
cout << r;
}