1.题目描述:点击打开链接
2.解题思路:本题利用二分法解决。根据题意,可以发现需要对区间的右端点排序即可。接下来就是二分时间x,那么怎么判断是否合法呢?首先用一个全局变量cnt表示第几次标记(好处是不需要每次都清空数组了),接下来对这段区间中不是cnt的点进行标记,用cur来统计标记的次数,如果最后cur<x,那么无解。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define rep(i,n) for(int i=0;i<(n);i++)
#define me(s) memset(s,0,sizeof(s))
#define pb push_back
#define lid (id<<1)
#define rid (id<<1|1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int N=10000+5;
P a[N];
int chk[N],cnt;
bool cmp(P a,P b)
{
return a.second<b.second;
}
int n;
bool ok(int d)
{
cnt++;
for(int i=0;i<n;i++)
{
int cur=0;
for(int k=a[i].first;k<a[i].second;k++)
{
if(cur==d)break;
if(chk[k]!=cnt)chk[k]=cnt,cur++;
}
if(cur<d)return 0;
}
return 1;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].first,&a[i].second);
sort(a,a+n,cmp);
int st=0,ed=10000;
while(st<ed-1)
{
int mid=st+ed>>1;
if(ok(mid))st=mid;
else ed=mid;
}
printf("%d\n",st*n);
}
}