题目
A.Carrot Cakes
乱七八糟算出两个时间比较一下就行了
又臭又长仅供参考
#include#define rep(i, j, k) for(int i = j;i <= k;i ++)#define rev(i, j, k) for(int i = j;i >= k;i --)using namespace std;typedef long long ll;int main() { ios::sync_with_stdio(false); int n, t, k, d; cin >> n >> t >> k >> d; int t1 = (n + k - 1) / k * t; int t2 = 0; int t3 = (n + k - 1) / k; int t4 = (d + t - 1) / t; int t5 = t3 - t4; if(t5 & 1) t2 = d + (t5 + 1) / 2 * t; else t2 = t4 * t + t5 / 2 * t; if(t2 < t1) puts("YES"); else puts("NO"); return 0;}
B.T-shirt buying
颜色数只有三个,开三个优先队列就行了
然后同一件衣服不要重复卖
#include#define rep(i, j, k) for(int i = j;i <= k;i ++)#define rev(i, j, k) for(int i = j;i >= k;i --)using namespace std;const int maxn = 200010;typedef long long ll;struct node { int x, y; bool operator < (const node &a) const { return x > a.x; }};priority_queue q[4];int n, m, v[maxn], a, b, p[maxn];int main() { ios::sync_with_stdio(false); cin >> n; rep(i, 1, n) cin >> p[i]; rep(i, 1, n) cin >> a, q[a].push((node){p[i], i}); rep(i, 1, n) cin >> b, q[b].push((node){p[i], i}); cin >> m; rep(i, 1, m) { cin >> a; while(!q[a].empty() && v[q[a].top().y]) q[a].pop(); if(!q[a].empty()) cout << q[a].top().x << " ", v[q[a].top().y] = 1, q[a].pop(); else cout << "-1 "; } return 0;}
C.Fountains
三种情况,都用c或d买,一个c一个d
第三种肥肠简单的
前面两种的话
对于新插入的物品,如果价格为x
那么查询一下价格<=(c-x)的物品中的最大beauty
然后两个物品组合一下就行了
查询的话,直接树状数组就可以了,O(nlogn)
需要注意保证是两个不同物品,不能只有一个
#include#define lb(x) (x & (-x))#define rep(i, j, k) for(int i = j;i <= k;i ++)#define rev(i, j, k) for(int i = j;i >= k;i --)using namespace std;typedef long long ll;struct node{ int x, y; char str[4]; void init() { scanf("%d %d %s", &x, &y, str); }}a[100010];int n, c, d, e, c1[100010], c2[100010];int ask(int *C, int i) { int ret = 0; while(i > 0) ret = max(ret, C[i]), i -= lb(i); return ret;}void ins(int *C, int i, int x) { while(i <= e) C[i] = max(C[i], x), i += lb(i);}int main() { cin >> n >> c >> d, e = max(c, d); int t1 = 0, t2 = 0, t3, t4 = 0, t5 = 0, ans = 0; rep(i, 1, n) { a[i].init(); if(a[i].str[0] == 'C' && a[i].y <= c) { if(a[i].x > t1) t1 = a[i].x; t3 = ask(c1, c - a[i].y); if(t3 != 0 && a[i].x + t3 > t4) t4 = a[i].x + t3; ins(c1, a[i].y, a[i].x); } if(a[i].str[0] == 'D' && a[i].y <= d) { if(a[i].x > t2) t2 = a[i].x; t3 = ask(c2, d - a[i].y); if(t3 != 0 && a[i].x + t3 > t5) t5 = a[i].x + t3; ins(c2, a[i].y, a[i].x); } } ans = max(t4, t5); if(t1 != 0 && t2 != 0 && t1 + t2 > ans) ans = t1 + t2; cout << ans; return 0;}
我还肥肠脑残地,取消了cin与stdio的同步后
同时用cin和scanf,然后WA了一发...
D.Field expansion
显然ans最大就是loga级别的
所以我们直接暴搜就行了
然后考虑到很骚的情况
a = b = 10W h = w = 1
ai = 2 n = 10W
这样的话我们用map防重就好了
很重要的一件事情 :
注意到题意说能放下
所以并没有h一定对应a,w一定对应b
也可以试试h怼b,w怼a!
#include#define rep(i, j, k) for(int i = j;i <= k;i ++)#define rev(i, j, k) for(int i = j;i >= k;i --)using namespace std;typedef long long ll;int a, b, h, w, n, c[100010];bool cmp(int x, int y) { return x > y;}typedef pair node;vector e;map p;int main() { ios::sync_with_stdio(false); cin >> a >> b >> h >> w >> n; rep(i, 1, n) cin >> c[i]; sort(c + 1, c + n + 1, cmp); node tmp; if(h >= a && w >= b || w >= a && h >= b) {puts("0");return 0;} e.push_back(make_pair(h, w)); for(int i = 1;i <= n;i ++) { int t = e.size(); for(int j = 0;j < t;j ++) { if(e[j].first < a) { tmp = make_pair(e[j].first * c[i], e[j].second); if(!p[tmp]) e.push_back(tmp), p[tmp] = 1; } if(e[j].second < b) { tmp = make_pair(e[j].first, e[j].second * c[i]); if(!p[tmp]) e.push_back(tmp), p[tmp] = 1; } } for(int j = 0;j < e.size();j ++) { if(e[j].first >= a && e[j].second >= b || e[j].first >= b && e[j].second >= a) { cout << i; return 0; } } } puts("-1"); return 0;}