- 题目考点:二分 + 验证答案
- 题目内容:给n种牌和一种Joker牌,问能合成几套牌,其中每一套牌要包含n种不同的牌(其中给定的n种牌中若有一种不够用,可以用Joker代替,Joker也只能在一套牌里出现一次)。
- 题目分析:二分答案,例如题目样例:
3 4 1 2 3 //即第一种牌1张,第二种2张,第三种三张,joker 4 张,每套牌3张,至少含三种不同的牌
我们来模拟验证答案为2、3、4时的答案:
观察到以下情形:
1、如图①和②,当第一种牌或者第二种牌不够用时,可以用joker替换;
2、如图①和②,使用的joker小于4,说明够用,则ans = 2 或 ans = 3能够组成 ;
3、如图③,当使用的joker大于m = 4,则说明joker不够用,不能组成;
4、如图③,当使用的joker大于ans = 4,则说明joker在不止一组中出现过,不符合题意。
因此代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 55;
int a[N];
int n, m;
bool jud(int mid)
{
LL ans = 0; //ans记得开logn long,有10分卡数据范围
for(int i = 1; i <= n; i++)
if(a[i] < mid) ans += mid - a[i]; //对应情形1
//cout<<' '<<ans << ' '<< (ans <= m && ans <= mid)<<'\n';
return ans <= m && ans <= mid; //对应情形2、3、4
}
int main()
{
scanf("%d%d", &n, &m);
int maxx = 0;
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), maxx = max(maxx, a[i]);
int l = 1, r = maxx * 2;
while(l < r)
{
int mid = l + r + 1 >> 1; //二分l = mid需要给和+1
//cout<<mid <<' '<<l <<' '<< r;
if(jud(mid)) l = mid;
else r = mid - 1;
}
cout<< l;
return 0;
}
京公网安备 11010502036488号