Description
一个人一天要喝 k k 瓶牛奶,如果冰箱里的牛奶不够瓶就全部喝完,目前冰箱里有 n n 瓶牛奶,给出每瓶牛奶的保质期,即还有几天会过期,过期的牛奶要被扔掉,再给出商店中瓶牛奶的保质期,问是否存在一种方案使得这个人不扔掉任何一瓶牛奶,如果有,他最多可以从商店买多少瓶牛奶
Input
第一行三个整数 n,m,k n , m , k 表示已有牛奶数量,商店里牛奶数量和每天喝的牛奶数量,之后输入 n n 个整数表示已有牛奶的保质期,最后 m m 个整数表示商店里 m m 瓶牛奶的保质期
Output
如果存在一种不用扔牛奶的方案则输出从商店里最多可以买多少瓶牛奶以及这些牛奶的编号,否则输出 −1 − 1
Sample Input
3 6 2
1 0 1
2 0 2 0 0 2
Sample Output
3
1 2 3
Solution
用 ai a i 表示第 i i 天还可以喝的牛奶数量,把商店的瓶牛奶按保质期排序,从第 107 10 7 天开始,对于第 i i 天,如果,那么多的牛奶只能放到之前喝,故把多余的 ai−k a i − k 瓶牛奶放到 ai−1 a i − 1 ,如果 ai≤k a i ≤ k ,那么只要 ai a i 不超过 k k ,且商店里还有保质期不小于的牛奶,就可以一直从商店买牛奶放到第 i i 天喝,以此类推,如果最终,说明喝不完,无解,否则看是否可以接着从商店里买牛奶即可,时间复杂度 O(107+mlog2m) O ( 10 7 + m l o g 2 m )
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 11111111
int n,m,k,a[maxn];
typedef pair<int,int>P;
P b[maxn];
vector<int>ans;
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
ans.clear();
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
int temp;
scanf("%d",&temp);
a[temp]++;
}
for(int i=1;i<=m;i++)scanf("%d",&b[i].first),b[i].second=i;
sort(b+1,b+m+1);
int j=m;
for(int i=10000000;i;i--)
{
if(a[i]>k)
{
a[i-1]+=a[i]-k;
continue;
}
while(j&&b[j].first>=i&&a[i]<k)ans.push_back(b[j].second),a[i]++,j--;
}
if(a[0]>k)printf("-1\n");
else
{
while(j&&a[0]<k)
ans.push_back(b[j].second),a[0]++,j--;
printf("%d\n",ans.size());
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');
}
}
return 0;
}