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個都買了最少花費。
那麼就可以這樣遞推
然後遍歷答案就可以了,因爲假設你最多能買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個三角形,嘗試求出 頂點順時針或者逆時針的編號並且任意起點都可以,以及三角形的切出順序,任意一個即可。
做法:其實這題我是不怎麼會的,題解也沒有看懂。但不過看了一位大佬的代碼,忽然好像就知道了。首先我們先考慮頂點編號,我們發現一條邊最多會使用兩次,對於只使用了一次的邊肯定就是凸包的邊了。我們考慮使用 運算來解決這個問題,對於給出的三角形首先進行 對邊用map進行標記記錄下共用的三角形的標號,同時對頂點進行異或,如果是共用邊,一個頂點異或兩次沒有影響,然後在map中找到任意一條只使用了一次的邊的兩個頂點,然後就可以用進行類似鏈表的操作得到答案。關於三角形的順序這個我倒是想到了,共用邊的兩個三角形,建立一個無向圖,然後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;
}