二分
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
你有n种牌,第i种牌的数目为ci。另外有一种特殊的牌:joker,它的数目是m。你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1套牌。比如,当n=3时,一共有4种合法的套牌:{1,2,3}, {J,2,3}, {1,J,3}, {1,2,J}。 给出n, m和ci,你的任务是组成尽量多的套牌。每张牌最多只能用在一副套牌里(可以有牌不使用)。
输入描述:
第一行包含两个整数n, m,即牌的种数和joker的个数。第二行包含n个整数ci,即每种牌的张数。
输出描述:
输出仅一个整数,即最多组成的套牌数目。
示例1
备注:
数据范围
50%的数据满足:2 < = n < = 5, 0 < = m < = 10^ 6, 0< = ci < = 200
100%的数据满足:2< = n < = 50, 0 < = m, ci <= 500,000,000。
解题思路
答案要求最大,那么如果我们假设使用ans个方案时答案合理,那么我们就要去尝试大于ans的部分,其余就是小于。
那么很明显的二分思路了。
如果当前个数小于mid的时候,说明就要用大王去填坑,最后判断够不够的大王即可。
#pragma GCC target("avx,sse2,sse3,sse4,popcnt") #pragma GCC optimize("O2,O3,Ofast,inline,unroll-all-loops,-ffast-math") #include <bits/stdc++.h> using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; typedef unsigned long long ull; typedef long double ld; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[40]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 50 + 7; int a[N]; int main() { int n = read(), m = read(); for (int i = 1; i <= n; ++i) a[i] = read(); int l = 0, r = 1e9, mid, ans; while (l <= r) { mid = r + l >> 1; ll cnt = 0; for (int i = 1; i <= n; ++i) if (a[i] < mid) cnt += mid - a[i]; if (cnt > mid or cnt > m) r = mid - 1; else ans = mid,l = mid + 1; } write(ans); return 0; }