Codeforces Round #610 (Div. 2) 簡要題解

http://codeforces.com/contest/1282
堅持下去誰也不知道結果是什麼,但不堅持我肯定會後悔的。

這場比賽自閉了,對我極其不友好,讀不懂,讀懂了又做不來。

A.Temporarily unavailable

題意:給一個區間[a,b],以及一個基站c,以及信號覆蓋範圍半徑r,一個人以單位速度從a到b運動,問過程中有多少時間不再基站信號範圍內。
做法:直接模擬即可,求出信號的區間,與原來的區間相比即可。

//#include <iostream>
//#include <algorithm>
//#include <stdio.h>
//#include <string.h>
//#include <vector>
//#include <math.h>
#include "bits/stdc++.h"
 
using namespace std;
 
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
//#define ls(x) tr[x].ls
//#define rs(x) tr[x].rs
//#define lowbit(x) x&-x
 
const int inf = 0x3f3f3f3f;
const int maxn = 200000 + 10;
typedef long long ll;
 
void solve() {
    ll a, b, c, r;
    cin >> a >> b >> c >> r;
    if (a > b) swap(a, b);
    int la = c - r;
    int lb = c + r;
    ll ans = 0;
    if (la <= a && lb >= b) {
        cout << 0 << endl;
        return;
    }
    if (la >= a && la <= b) ans += la - a;
    if (lb <= b && lb >= a) ans += b - lb;
    if (ans == 0) ans = b - a;
    cout << ans << endl;
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

B - K for the Price of One

這道題自閉的開始。題目又長,英文又不好,不想看,他們口嗨了一句,k個優惠只能用一次。我居然當真了,然後WA了,後來又看見必須要有k個才能用。。。然後就寫了假算法,最後知道題意,想了個dp,想太複雜了放棄了,跟着它們亂搞了一個二分答案過去了?????…
題意:給你n個物品的價值,以及你擁有的錢,如果你能買任意k箇中最貴的那一個,那麼另外k-1個免費獲得。問最多能得到多少個。
做法:其實不復雜的,首先排一個序,我們想象一個狀態d[i]表示前i個都買了最少花費。
那麼就可以這樣遞推d[i]=a[i]+(i>=k)?s[ik]:s[i1]d[i]=a[i]+(i>=k)?s[i-k]:s[i-1]
然後遍歷答案就可以了,因爲假設你最多能買x個,那麼這x個一定是前x個。

//#include <iostream>
//#include <algorithm>
//#include <stdio.h>
//#include <string.h>
//#include <vector>
//#include <math.h>
#include "bits/stdc++.h"
 
using namespace std;
 
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
//#define ls(x) tr[x].ls
//#define rs(x) tr[x].rs
//#define lowbit(x) x&-x
 
const int inf = 0x3f3f3f3f;
const int maxn = 200000 + 10;
typedef long long ll;
ll n, p, k, a[maxn], s[maxn];
void solve() {
    cin >> n >> p >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    int ans = 0;
    s[0] = 0;
    for (int i = 1; i <= n; i++) {
        if (i < k) s[i] = s[i - 1] + a[i];
        else s[i] = s[i - k] + a[i];
        if (s[i] <= p) ans = i;
    }
    cout << ans << endl;
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

C - Petya and Exam

這道題原諒我英語水平不好。照着翻譯看了半天才看懂。
題意:給出題目中所說的人解決一個困難和簡單問題所需要的時間,以及總時間和題目的數量以及難度。最後給出每個題目變成"強制性"的時間,如果到了題目變成了強制性沒有完成任何一道強制性題目,都會得零分,當然你可以提前離場。問最多能得多少分,一個題目一分。
做法:按照變成強制性的時間從小到大進行排序,記錄先前變成強制性題目的數量,並與ti-1進行比較如果過大就零分,過小就優先解決後面的簡單的問題,然後更新答案。這樣貪心即可。

//#include <iostream>
//#include <algorithm>
//#include <stdio.h>
//#include <string.h>
//#include <vector>
//#include <math.h>
#include "bits/stdc++.h"
 
using namespace std;
 
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
//#define ls(x) tr[x].ls
//#define rs(x) tr[x].rs
//#define lowbit(x) x&-x
 
const int inf = 0x3f3f3f3f;
const int maxn = 200000 + 10;
typedef long long ll;
struct node {
    int f;
    ll t;
} p[maxn];
bool cmp(node a, node b) { return a.t < b.t; }
 
int n;
ll t, a, b;
void solve() {
    cin >> n >> t >> a >> b;
    int cnta = 0, cntb = 0;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].f;
        if (p[i].f) cntb++;
        else cnta++;
    }
    for (int i = 1; i <= n; i++) cin >> p[i].t;
    sort(p + 1, p + n + 1, cmp);
    p[n + 1].t = t + 1;
    ll ans = 0, c1 = 0, c2 = 0;
    for (int i = 1; i <= n + 1; i++) {
        ll tmp = c1 * a + c2 * b;
        ll time = p[i].t - 1 - tmp;
        if (time >= 0) {
            ll ta = min(time / a, cnta - c1);
            time -= ta * a;
            ll tb = min(time / b, cntb - c2);
            ans = max(ans, ta + tb + c1 + c2);
        }
        if (p[i].f) c2++;
        else c1++;
    }
    cout << ans << endl;
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

D - Enchanted Artifact

這是一個交互式問題
又是照着翻譯看的
題意:後臺有一個字符串長度爲n,只由ab組成,你可通過最多n+2次詢問,嘗試得出字符串。每次你可以輸出一個字符串,如果字符串完全匹配,則結束程序,否則給出不同的價值,這個價值表示其中一個字符串需要刪除,變換多少次。
做法:首先用定義兩個最長的全a和全b字符串,然後詢問兩次,這樣可以判斷字符串長度n,然後就可以挨着一位一位的判斷了,最壞情況下剛剛n+2次。

//#include <iostream>
//#include <algorithm>
//#include <stdio.h>
//#include <string.h>
//#include <vector>
//#include <math.h>
#include "bits/stdc++.h"
 
using namespace std;
 
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
//#define ls(x) tr[x].ls
//#define rs(x) tr[x].rs
//#define lowbit(x) x&-x
 
const int inf = 0x3f3f3f3f;
const int maxn = 200000 + 10;
typedef long long ll;
 
int query(string s) {
    cout << s << endl;
    int ans;
    cin >> ans;
    if (ans <= 0) exit(0);
    return ans;
}
 
int main() {
    string s1, s2;
    for (int i = 0; i < 300; i++)
        s1 += 'a', s2 += 'b';
    int na = 300 - query(s1);
    int nb = 300 - query(s2);
    int n = na + nb;
    string ans;
    for (int i = 0; i < n; i++) ans += 'a';
    if (nb == 0) {
        query(ans);
    }
    int tmp = nb;
    for (int i = 0; i < n; i++) {
        ans[i] = 'b';
        int xx = query(ans);
        if (xx > tmp) {
            ans[i] = 'a';
        } else {
            tmp = xx;
        }
    }
    return 0;
}

E - The Cake Is a Lie

還是照着翻譯看的
題意:給出一個n個點凸多邊形,頂點用1-n隨便編號,現在把他切成n-2個三角形,任意亂序給出n-2個三角形,嘗試求出 頂點順時針或者逆時針的編號並且任意起點都可以,以及三角形的切出順序,任意一個即可。
做法:其實這題我是不怎麼會的,題解也沒有看懂。但不過看了一位大佬的代碼,忽然好像就知道了。首先我們先考慮頂點編號,我們發現一條邊最多會使用兩次,對於只使用了一次的邊肯定就是凸包的邊了。我們考慮使用 xorxor運算來解決這個問題,對於給出的三角形首先進行 對邊用map進行標記記錄下共用的三角形的標號,同時對頂點進行異或,如果是共用邊,一個頂點異或兩次沒有影響,然後在map中找到任意一條只使用了一次的邊的兩個頂點,然後就可以用xorxor進行類似鏈表的操作得到答案。關於三角形的順序這個我倒是想到了,共用邊的兩個三角形,建立一個無向圖,然後dfs,從葉子向上輸出就可以了。

//#include <iostream>
//#include <algorithm>
//#include <stdio.h>
//#include <string.h>
//#include <vector>
//#include <math.h>
#include "bits/stdc++.h"
 
using namespace std;
 
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
//#define ls(x) tr[x].ls
//#define rs(x) tr[x].rs
//#define lowbit(x) x&-x
 
const int inf = 0x3f3f3f3f;
const int maxn = 200000 + 10;
typedef long long ll;
map<pair<int, int>, vector<int> > mp;
vector<int> p[maxn];
int n, a, b, c, v[maxn], vis[maxn];
vector<int> pp;
 
void dfs(int u, int f) {
    for (auto v:p[u]) {
        if (v == f) continue;
        dfs(v, u);
    }
    cout << u << ' ';
}
 
void solve() {
    mp.clear();
 
    cin >> n;
    for (int i = 0; i <= n + 1; i++) {
        v[i] = 0;
        p[i].clear();
    }
 
    for (int i = 1; i <= n - 2; i++) {
        cin >> a >> b >> c;
        if (a > b) swap(a, b);
        if (b > c) swap(b, c);
        if (a > b) swap(a, b);
        v[a] ^= b, v[a] ^= c;
        v[b] ^= a, v[b] ^= c;
        v[c] ^= b, v[c] ^= a;
        mp[{a, b}].push_back(i);
        mp[{b, c}].push_back(i);
        mp[{a, c}].push_back(i);
    }
    for (auto H:mp) {
        if (H.second.size() == 1) {
            a = H.first.first;
            b = H.first.second;
            break;
        }
    }
    cout << a << ' ' << b << ' ';
    for (int i = 0; i < n - 2; i++, swap(a, b)) cout << (a ^= v[b]) << ' ';
    cout << endl;
    for (auto H:mp) {
        if (H.second.size() == 2) {
            p[H.second[0]].push_back(H.second[1]);
            p[H.second[1]].push_back(H.second[0]);
        }
    }
    dfs(1, 0);
//    cout << pp.size() << endl;
//    for (auto x:pp) {
//        cout << x << " ";
//    }
    cout << endl;
}
 
int main() {
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章