解决虫洞 (ZCO 2012)
Solving Wormholes (ZCO 2012)
描述:
今年是2102年,今天是ZCO的日子。今年有 N 场比赛,您知道每场比赛的开始和结束时间。您必须参加其中一场比赛。不同的比赛可能会重叠。不同比赛的时长可能不同
考试中心只有一个。有一个虫洞 V 可以把你从你家送到考试中心,另一个虫洞 W 可以把你从考试中心送回你家。显然,通过虫洞运输不需要任何时间;它是瞬时的。但是虫洞只能在特定的固定时间使用,这些你都知道。
所以,你用V虫洞到达考场,可能等下一次比赛开始前一段时间,参加比赛,可能再等一段时间再用W虫洞return 回家。如果你在时间 t1 通过 V 虫洞离开并在时间 t2 通过 W 虫洞返回,那么你花费的总时间是 (t2 - t1 + 1)。您的目标是花费尽可能少的总体时间,同时确保您参加其中一项比赛。
如果可能的话,您可以正好在比赛开始时间到达中心。如果可能的话,你可以在比赛结束的那一刻离开考场。你可以假设你总是能够参加至少一场比赛——也就是说,总会有一场比赛,前面有一个 V 虫洞,后面有一个 W 虫洞。
例如,假设有 3 场比赛,(开始,结束)时间分别为 (15,21)、(5,10) 和 (7,25)。假设V虫洞在4、14、25、2时间可用,W虫洞在13、21时间可用,那么你可以在14时间从V虫洞离开,从15时间开始参加比赛到21点,然后在21点使用W虫洞回家。因此你花费的时间是(21 - 14 + 1)= 8。你可以检查你不能做得比这更好。
输入:
第一行包含3个space分隔的整数N、X、Y,其中N为比赛次数,X为虫洞V可使用的次数,Y为次数可以使用虫洞 W 的时间实例。接下来的 N 行描述了每场比赛。这 N 行中的每一行包含两个 space 分隔的整数 S 和 E,其中 S 是特定比赛的开始时间,E 是该比赛的结束时间,S < E。下一行包含 X space 分隔的整数是可以使用虫洞 V 的时间实例。下一行包含 Y space 个分隔的整数,它们是可以使用虫洞 W 的时间实例。
输出:
打印包含单个整数的一行,即参加比赛所需花费的最短时间。
我的代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) r=0;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) l=s-1;
return arr[l];
}
int main() {
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}
我尝试的是对下限和上限使用二进制搜索。和 return 列表中最接近的整数。这应该导致最低的差异。这段代码在 90% 的测试用例中都达到了 AC,但是有两个测试用例的答案是错误的。
正确代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) return -1;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) return -1;
return arr[l];
}
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
if(u==-1 or l==-1) continue;
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}
描述:
今年是2102年,今天是ZCO的日子。今年有 N 场比赛,您知道每场比赛的开始和结束时间。您必须参加其中一场比赛。不同的比赛可能会重叠。不同比赛的时长可能不同
考试中心只有一个。有一个虫洞 V 可以把你从你家送到考试中心,另一个虫洞 W 可以把你从考试中心送回你家。显然,通过虫洞运输不需要任何时间;它是瞬时的。但是虫洞只能在特定的固定时间使用,这些你都知道。
所以,你用V虫洞到达考场,可能等下一次比赛开始前一段时间,参加比赛,可能再等一段时间再用W虫洞return 回家。如果你在时间 t1 通过 V 虫洞离开并在时间 t2 通过 W 虫洞返回,那么你花费的总时间是 (t2 - t1 + 1)。您的目标是花费尽可能少的总体时间,同时确保您参加其中一项比赛。
如果可能的话,您可以正好在比赛开始时间到达中心。如果可能的话,你可以在比赛结束的那一刻离开考场。你可以假设你总是能够参加至少一场比赛——也就是说,总会有一场比赛,前面有一个 V 虫洞,后面有一个 W 虫洞。
例如,假设有 3 场比赛,(开始,结束)时间分别为 (15,21)、(5,10) 和 (7,25)。假设V虫洞在4、14、25、2时间可用,W虫洞在13、21时间可用,那么你可以在14时间从V虫洞离开,从15时间开始参加比赛到21点,然后在21点使用W虫洞回家。因此你花费的时间是(21 - 14 + 1)= 8。你可以检查你不能做得比这更好。
输入:
第一行包含3个space分隔的整数N、X、Y,其中N为比赛次数,X为虫洞V可使用的次数,Y为次数可以使用虫洞 W 的时间实例。接下来的 N 行描述了每场比赛。这 N 行中的每一行包含两个 space 分隔的整数 S 和 E,其中 S 是特定比赛的开始时间,E 是该比赛的结束时间,S < E。下一行包含 X space 分隔的整数是可以使用虫洞 V 的时间实例。下一行包含 Y space 个分隔的整数,它们是可以使用虫洞 W 的时间实例。
输出:
打印包含单个整数的一行,即参加比赛所需花费的最短时间。
我的代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) r=0;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) l=s-1;
return arr[l];
}
int main() {
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}
我尝试的是对下限和上限使用二进制搜索。和 return 列表中最接近的整数。这应该导致最低的差异。这段代码在 90% 的测试用例中都达到了 AC,但是有两个测试用例的答案是错误的。
正确代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <bits/stdc++.h>
#define loop(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)
#define ll long long
#define inf 9223372036854775807
#define printgrid(arr,m,n){cout<<"[";for(int i=0;i<m;++i){if(i!=0)cout<<" ";cout<<"[";for(int j=0;j<n;++j){cout<<arr[i][j];if(j!=n-1)cout<<" ";}cout<<"]";if(i!=m-1)cout<<endl;}cout<<"]"<<endl;}
using namespace std;
int searchl(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if (r<0) return -1;
return arr[r];
}
int searchh(int *arr,int s,int v)
{
int l=0;
int r=s-1;
while(l<=r)
{
int m = (l+r)/2;
if (arr[m] == v) return v;
if(arr[m]<v)
{
l = m + 1;
} else {
r = m - 1;
}
}
if(l>s-1) return -1;
return arr[l];
}
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
int n,x,y;
cin>>n>>x>>y;
vector<pair<int,int>> v(n);
int a[x];
int b[y];
loop(i,n) cin >> v[i].first >> v[i].second;
loop(i,x) cin >> a[i];
loop(i,y) cin >> b[i];
sort(a,a+x);
sort(b,b+y);
int mn = 0x7fffffff;
int l;
int u;
loop(i,n)
{
l = searchl(a,x,v[i].first);
u = searchh(b,y,v[i].second);
if(u==-1 or l==-1) continue;
mn = min(mn,(u-l+1));
}
cout << mn << endl;
}