目录
Contest Info
Solved | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
5/7 | O | O | O | O | Ø | - | - |
- O 在比赛中通过
- Ø 赛后通过
- ! 尝试了但是失败了
- - 没有尝试
Solutions
A. Cards for Friends
题意:
给你一个
w
w
w x
h
h
h的明信片,当
h
h
h或
w
w
w为偶数时可以剪成两份,问你最终能剪出来的数量是否比
n
n
n大。
思路:
刚开始总数为
1
1
1,每剪一次乘上
2
2
2。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)
void err() {
cout << endl;
}
template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' '; err(args...);
}
template <class T> inline void read(T &x) {
int f = 0; x = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (f) x = -x;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll tot = 1;
void work(ll n) {
while (n % 2 == 0) {
n /= 2;
tot <<= 1;
}
}
ll w, h, n;
void solve() {
cin >> w >> h >> n;
tot = 1;
work(w);
work(h);
cout << (tot >= n? "YES" : "NO") << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
cout << fixed << setprecision(20);
int _T = 1;
cin >> _T;
while (_T--) solve();
}
B. Fair Division
题意:
给出
n
n
n颗糖果,每颗糖果的重量为
1
1
1或者
2
2
2,问这些糖果是否可以均分成重量相同的两份。
思路:
若
1
1
1的数量不为偶数肯定不行,接下来考虑
2
2
2的数量。当
2
2
2的数量为奇数时考虑能否用两个
1
1
1来使之平衡。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)
void err() {
cout << endl;
}
template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' '; err(args...);
}
template <class T> inline void read(T &x) {
int f = 0; x = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (f) x = -x;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int num1, num2, n;
void solve() {
cin >> n;
num1 = num2 = 0;
for (int i = 1, t; i <= n; ++i) {
cin >> t;
if (t == 1) num1++;
else num2++;
}
if (num1 & 1) {
cout << "NO" << endl;
return;
}
if (num2 % 2 == 0) {
cout << "YES" << endl;
return;
}
if (num1 >= 2) {
cout << "YES";
}
else cout << "NO";
cout << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
cout << fixed << setprecision(20);
int _T = 1;
cin >> _T;
while (_T--) solve();
}
C. Long Jumps
题意:
给你一段元素权值为正整数的序列,你可以从任意一点出发,每次跳到当前点的后第当前权值个点,直到跳出序列。问你一路上经过的点权值和最大是多少。
思路:
很明显要记忆化。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)
void err() {
cout << endl;
}
template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' '; err(args...);
}
template <class T> inline void read(T &x) {
int f = 0; x = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (f) x = -x;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 7;
ll dp[N], a[N];
ll n;
ll dfs(ll u) {
if (u > n) return 0;
if (dp[u]) return dp[u];
dp[u] += a[u] + dfs(u + a[u]);
return dp[u];
}
void solve() {
cin >> n;
ll maxx = -INF;
for (ll i = 1; i <= n; ++i) {
cin >> a[i];
dp[i] = 0;
}
for (ll i = 1; i <= n; ++i) {
maxx = max(maxx, dfs(i));
}
cout << maxx << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
cout << fixed << setprecision(20);
int _T = 1;
cin >> _T;
while (_T--) solve();
}
D. Even-Odd Game
题意:
给你一段元素权值为正整数的序列,两个人可以不放回地取出里面的元素。先手取权值为偶数的数时,将自己的分数加上当前数,否则直接丢弃。后手则加奇数,直接弃偶数。问最优情况下的获胜情况。
思路:
想一下发现我们每次可以贪心的去取最大值,要么让对方取不到最大值,要么就能让自己取到最大值。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)
void err() {
cout << endl;
}
template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' '; err(args...);
}
template <class T> inline void read(T &x) {
int f = 0; x = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (f) x = -x;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 7;
ll a[N];
int n;
void solve() {
cin >> n;
ll ansOdd = 0, ansEven = 0;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
sort(a + 1, a + 1 + n, greater<ll>());
for (int i = 1; i <= n; ++i) {
if ((i - 1) & 1) {
if (a[i] & 1) ansOdd += a[i];
} else if (a[i] % 2 == 0) ansEven += a[i];
}
if (ansOdd > ansEven) cout << "Bob" << endl;
else if (ansOdd < ansEven) cout << "Alice" << endl;
else cout << "Tie" << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
cout << fixed << setprecision(20);
int _T = 1;
cin >> _T;
while (_T--) solve();
}
E. Correct Placement
题意:
有
n
n
n个人,第
i
i
i个人的高和宽为
h
i
h_i
hi,
w
i
w_i
wi。选
i
i
i,
j
j
j两个人,若满足条件
h
j
h_j
hj <
h
i
h_i
hi and
w
j
w_j
wj <
w
i
w_i
wi 或者
w
j
w_j
wj <
h
i
h_i
hi and
h
j
h_j
hj <
w
i
w_i
wi,则称第
j
j
j个人可以排在第
i
i
i个人前面。现在问每个人是否有人可以在他前面。
思路:
我们考虑将
h
i
h_i
hi设为
h
i
h_i
hi和
w
i
w_i
wi中的较小值,
w
i
w_i
wi为
h
i
h_i
hi和
w
i
w_i
wi中的较大值,那么就只用判断
h
j
h_j
hj <
h
i
h_i
hi and
w
j
w_j
wj <
w
i
w_i
wi的条件了(贪心地让小的和小的比,大的和大的比)。那么接下来我们以
h
h
h为第一关键字,
w
w
w为第二关键字,由小到大
s
o
r
t
sort
sort一下。然后以
1
1
1为最小的元素,遍历数组,判断条件。期间记录下遍历过的值中
w
w
w最小的位置在哪里,当
h
h
h的值变化两次后(因为要严格小于),则改变最小的元素所在的位置。注意当
h
h
h值变化达到两次后,下次只用再变化一次就行了。因为变化对上一次和下一次都是有贡献的。
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define dbg(x...) \
do { \
cout << #x << " -> "; \
err(x); \
} while (0)
void err() {
cout << endl;
}
template <class T, class... Ts>
void err(const T& arg, const Ts&... args) {
cout << arg << ' '; err(args...);
}
template <class T> inline void read(T &x) {
int f = 0; x = 0; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if (f) x = -x;
}
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 7;
struct Friend{
int h, w, id;
Friend(int h, int w, int id) : h(h), w(w), id(id) {}
Friend () {}
}f[N];
bool cmp(Friend a, Friend b) {
if (a.h == b.h) return a.w < b.w;
return a.h < b.h;
}
int n, ans[N];
void solve() {
read(n);
for (int i = 1, h, w; i <= n; ++i) {
read(h), read(w);
f[i] = Friend(min(h, w), max(h, w), i);
ans[i] = -1;
}
sort(f + 1, f + 1 + n, cmp);
int now = 1, nxt = 1, minn = f[1].w, sta = 0;
for (int i = 2; i <= n; ++i) {
if (f[i].h != f[i - 1].h) sta++;
if (sta > 1) {
sta = 1;
now = nxt;
}
if (f[i].h > f[now].h && f[i].w > f[now].w) {
ans[ f[i].id ] = f[now].id;
}
if (minn > f[i].w) {
minn = f[i].w;
nxt = i;
}
}
for (int i = 1; i <= n; ++i) {
printf("%d%c", ans[i], " \n"[i == n]);
}
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(nullptr);cout.tie(nullptr);
// cout << fixed << setprecision(20);
int _T = 1;
read(_T);
while (_T--) solve();
}