Codeforces Round #413(Div. 1 + Div. 2, combined)——ABCD

题目在这里

 

A.Carrot Cakes

乱七八糟算出两个时间比较一下就行了

又臭又长仅供参考

#include <bits/stdc++.h>

#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;
}
View Code

 

B.T-shirt buying

颜色数只有三个,开三个优先队列就行了

然后同一件衣服不要重复卖

#include <bits/stdc++.h>

#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 <node> 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;
}
View Code

 

C.Fountains

三种情况,都用c或d买,一个c一个d

第三种肥肠简单的

前面两种的话

对于新插入的物品,如果价格为x

那么查询一下价格<=(c-x)的物品中的最大beauty

然后两个物品组合一下就行了

查询的话,直接树状数组就可以了,O(nlogn)

需要注意保证是两个不同物品,不能只有一个

 #include <bits/stdc++.h>

#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;
}
View Code

我还肥肠脑残地,取消了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 <bits/stdc++.h>

#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<ll, ll> node;

vector <node> e;

map <node,bool> 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;
}
View Code

 

posted @ 2017-05-12 03:31  ztztyyy  阅读(165)  评论(0编辑  收藏  举报