Practice Link
Solved | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
5/7 | O | O | O | O | Ø | - | - |
题意:
给你一个 w w w x h h h的明信片,当 h h h或 w w w为偶数时可以剪成两份,问你最终能剪出来的数量是否比 n n n大。
思路:
刚开始总数为 1 1 1,每剪一次乘上 2 2 2。
#include
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();
}
题意:
给出 n n n颗糖果,每颗糖果的重量为 1 1 1或者 2 2 2,问这些糖果是否可以均分成重量相同的两份。
思路:
若 1 1 1的数量不为偶数肯定不行,接下来考虑 2 2 2的数量。当 2 2 2的数量为奇数时考虑能否用两个 1 1 1来使之平衡。
#include
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();
}
题意:
给你一段元素权值为正整数的序列,你可以从任意一点出发,每次跳到当前点的后第当前权值个点,直到跳出序列。问你一路上经过的点权值和最大是多少。
思路:
很明显要记忆化。
#include
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();
}
题意:
给你一段元素权值为正整数的序列,两个人可以不放回地取出里面的元素。先手取权值为偶数的数时,将自己的分数加上当前数,否则直接丢弃。后手则加奇数,直接弃偶数。问最优情况下的获胜情况。
思路:
想一下发现我们每次可以贪心的去取最大值,要么让对方取不到最大值,要么就能让自己取到最大值。
#include
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();
}
题意:
有 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
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();
}