codeforces 767 D. Cartons of milk(二分+貪心+雙指針)

http://codeforces.com/contest/767/problem/D
題意:自己已經擁有n瓶牛奶,每瓶保質期已知,超市有m瓶牛奶,保質期已知,每天喝掉k瓶牛奶,不足k瓶全部喝光,過期牛奶就會扔掉,問最多買多少牛奶可以不用扔掉

思路:自然能想到購買的時候貪心的買,從保質期大的開始買,如果保質期大的都需要扔掉,那麼自然保質期小的也需要扔掉,那麼這個牛奶數目就可以通過二分來check
關鍵問題這道題數據偏大,如果每次檢查答案把所有牛奶拿出來重新排序的話會TLE(可能我寫的太菜)
比較優秀的寫法是通過最初將b數組排序,每次二分最初購買的位置x,然後檢查x-n都購買是否符合要求,check的時候採用雙指針,哪一個優小優先選擇哪一個,如果一個選完只能選擇另一個,然後用一個day記錄當前天數,如果現在喝的小於day那麼自然不符合要求

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
 
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<P, int> LP;
const int inf = 0x3f3f3f3f;
const int N = 1e7 + 100;
const ll mod = 1e18+7;
const int base=131;
inline ll mul(ll x,ll y) { return (x*y-(ll)((long double)x*y/mod)*mod+mod)%mod;}
inline ll ksm(ll a,ll b) {ll ans=1;while(b){if(b&1)ans=mul(ans,a);a=mul(a,a),b>>=1;}return ans;}
 
 
ll n,m,k,x,y,cx,cy,t;
ll ans,cnt,sum,flag,res;
 
ll a[N];//,b[N];
ll num[N];
 
//ll tree[N];
string s;
 
//vector<int> v[N];
 
ll mx;
 
P b[1000005];
bool cmp(P a,P b)
{
	return a.fi<b.fi;
}
bool check(ll x)
{
	int i=0,j=x,day=0;
	int tk=k;
	while(i<n||j<m)
	{
 
		if(a[i]<b[j].fi&&i<n||j==m)
		{
			if(a[i]<day) return 0;
			tk--;
			i++;
		}
		else
		{
			if(b[j].fi<day) return 0;
			tk--;
			j++;
		}
		//show3(i,j,day)
		if(tk==0) day++,tk=k;
	}
	return 1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
 
	cin>>n>>m>>k;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<m;i++) cin>>b[i].fi,b[i].se=i+1;
	sort(a,a+n);
	sort(b,b+m,cmp);
 
	int l=0,r=m;
	ans=-1;
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	if(ans==-1) return cout<<-1,0;
	cout<<m-ans<<endl;
	for(int i=ans;i<m;i++)
	{
		cout<<b[i].se<<" ";
	}
	//cout<<check(0)<<endl;
 
 
}
/*
數據範圍
是否爆int
空間大小
時間複雜度
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章