Codeforces 985 最短水桶分配 沙堆构造 贪心单调对列
A
B
/* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) make_pair(a,b) #define pb push_back const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; using namespace std; typedef long long ll; inline void read(int &v) { v = 0; char c = 0; int p = 1; while (c < '0' || c > '9') { if (c == '-') { p = -1; } c = getchar(); } while (c >= '0' && c <= '9') { v = (v << 3) + (v << 1) + c - '0'; c = getchar(); } v *= p; } const long long mod = 1e9 + 7; const int N = 1e5 + 5; int n; char f[2005][2005]; int num[2005]; int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { scanf("%s", f[i] + 1); } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (f[i][j] == '1') { num[j]++; } } } int flag; for (int i = 1; i <= n; i++) { flag = 1; for (int j = 1; j <= m; j++) { if (f[i][j] == '1' && num[j] == 1) { flag = 0; break; } } if (flag) { cout << "YES" << endl; return 0; } } cout << "NO" << endl; return 0; }
C
/* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) make_pair(a,b) #define pb push_back const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; using namespace std; typedef long long ll; inline void read(int &v) { v = 0; char c = 0; int p = 1; while (c < '0' || c > '9') { if (c == '-') { p = -1; } c = getchar(); } while (c >= '0' && c <= '9') { v = (v << 3) + (v << 1) + c - '0'; c = getchar(); } v *= p; } const long long mod = 1e9 + 7; const int N = 1e5 + 5; int n; ll num[N]; priority_queue<ll, vector<ll>, less<ll> >que; queue<ll> q; int main() { int n, k; ll l; ll minn = INT_MAX; ll anser = 0; cin >> n >> k >> l; for (int i = 1; i <= n * k; i++) { scanf("%d", &num[i]); minn = min(minn, num[i]); } int cnt = 0; if (k == 1) { for (int i = 1; i <= n * k; i++) { if (num[i] > minn + l) { cout << 0 << endl; return 0; } anser += num[i]; } cout << anser << endl; return 0; } //cout<<minn<<endl; for (int i = 1; i <= n * k; i++) { if (num[i] <= minn + l) { que.push(num[i]); } else { q.push(num[i]); } } while (n--) { for (int i = 1; i <= k - 1; i++) { if (que.empty()) { cout << 0 << endl; return 0; } if (q.empty()) { if (que.size() > 1) { //cout<<que.top()<<endl; que.pop(); } else { cout << 0 << endl; return 0; } } else { //cout<<q.front()<<endl; q.pop(); } } //cout<<que.top()<<endl; ll now = que.top(); que.pop(); //cout<<endl; if (now > minn + l) { cout << 0 << endl; return 0; } else { anser += now; } } cout << anser << endl; return 0; }
D. Sand Fortress
给你N高度的沙子 要求你堆出刚好N高度的沙子 相邻的两个沙子差距不超过1 第一堆沙子不超过H
解:
①
官方题解:
先考虑金字塔型1到K到1 这样得到的总数为k*(k+1)/2-k=k2
然后我们贪心把剩下的n-k2都用k来放 再需要用的总数就是
可以证明对于任意k从2到 这个函数从1开始是递增的
然后贪心地把金字塔尽量往左移 即让初始的h1=min(k,H)
则左移后的沙子总数为
所以我们需要做的是找到最大的k使得当h1=min(k,H)时
当恰好为n时 不用补充 小于n时 用k去补充
#include <bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) typedef long long li; using namespace std; const int INF = 2e9; li n, h; bool check(li maxh){ li k = min(h, maxh); li cnt = maxh * maxh - k * (k - 1) / 2; return (cnt <= n); } li get(li maxh){ li k = min(h, maxh); li cnt = maxh * maxh - k * (k - 1) / 2; li len = (2 * maxh - 1) - (k - 1); n -= cnt; return len + (n + maxh - 1) / maxh; } int main() { scanf("%lld%lld", &n, &h); li l = 1, r = INF; while (l < r - 1){ li m = (l + r) / 2; if (check(m)) l = m; else r = m; } printf("%lld\n", check(r) ? get(r) : get(l)); return 0; }
②(和官方差不多)
构造两种
第一种为三角形 第二种为梯形
两种分别二分构造 然后取最小值即可
E. Pencils and Boxes
给你一个N个数字的数组,要求你把每个数字都放入一个盒子
每个数字只属于一个盒子 每个盒子至少要有K个数字 每个盒子的极差不超过d
能实现的话YES 否则NO
解:
贪心 单调队列
先排序 然后贪心 很容易想到一个盒子里能放多少连续的就尽量放多少
通过单调队列实现能放多少尽量放多少的操作
/* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a,b) make_pair(a,b) #define pb push_back const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}}; using namespace std; typedef long long ll; inline void read(int &v) { v = 0; char c = 0; int p = 1; while (c < '0' || c > '9') { if (c == '-') { p = -1; } c = getchar(); } while (c >= '0' && c <= '9') { v = (v << 3) + (v << 1) + c - '0'; c = getchar(); } v *= p; } const long long mod = 1e9 + 7; const int N = 5e5 + 5; int n; int num[N]; int q[N]; int main() { int k, d; read(n), read(k), read(d); for (int i = 1; i <= n; i++) { read(num[i]); } int now; sort(num + 1, num + 1 + n); int head = 1; int tail = 1; for (int i = k; i <= n; i++) { while (head <= tail && num[i] - num[q[head] + 1] > d) { head++; } if (head <= tail && i - q[head] >= k) { q[++tail] = i; } } if (q[tail] == n) { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }
F