【Panasonic Programming Contest 2024(AtCoder Beginner Contest 354)】题解
DIRECTORY
†♪†A - Exponential Plant
问题陈述
高桥正在种植一棵植物。它发芽时的高度是 0 , c m 0,\mathrm{cm} 0,cm 。把发芽日看作 0 0 0 日,它的高度增加了 2 i c m 2^i\,\mathrm{cm} 2icm 天 i i i 的夜晚 ( 0 ≤ i ) (0 \le i) (0≤i) 。
高桥的高度为 H c m H\,\mathrm {cm} Hcm 。
每天早晨,高桥都会对照这株植物测量自己的身高。求这株植物的高度严格大于高桥早晨身高的第一天。
分析
循环,拿一个 sum
存贮当前高度,每次加上
2
i
2^i
2i
c
m
{cm}
cm, 直到 sum
>
>
> h
代码:
int h;
int sum;
int k;
void solve() {
// 竞赛程序
cin >> h;
int sum = 0;
int k = 0;
while(sum < h) {
int c = 1;
for(int i = 0; i < k; i++) {
c *= 2;
}
sum += c;
k++;
}
cout << k << endl;
}
⁎⁑⁂⁕B - AtCoder Janken 2
问题陈述
翻译见B - AtCoder Janken 2翻译, 我写过的
分析
按原题意思照做即可,详细见代码
void solve(){
// 竞赛程序
int n; cin >> n;
vector<string> s(n);
vector<int> c(n);
long long sum = 0; //分数总和
for(int i = 0; i < n; i++){
cin >> s[i] >> c[i];
sum += c[i]; //分数全部相加
}
sort(s.begin(), s.end()); //排序
cout << s[(sum % n)] << endl; //取模后输出
}
⟬௹⟭C - AtCoder Magics
问题陈述
翻译见{ABC354(PPC2024)} C - AtCoder Magics翻译,我写过了
分析
思路:对
A
A
A关键字排序后,考虑最后的结果
C
C
C关键字应该是什么顺序,不难发现,最后
C
C
C应该也是升序,若不是升序则仍然存在可以被丢掉的卡片。因此对
A
A
A排序后对
C
C
C倒着遍历一遍,碰见
C
i
−
1
>
C
i
C_i - 1 > C_i
Ci−1>Ci删去i - 1
,让
C
C
C也升序。这里不能正着遍历,因为第一张卡片
A
A
A最小,仍然可能被丢掉,但是最后一张
A
A
A最大,一定会保留
代码
int n;
int ans[N];
struct user {
int x, y, id;
} a[N];
bool cmp(user a, user b) {
return a.x > b.x;
}
void solve() {
// 竞赛程序
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y, a[i].id = i;
sort(a + 1, a + 1 + n, cmp);
int l = 1, cnt = 1;
ans[a[1].id] = 1;
for(int i = 2; i <= n; i++)
if(!(a[l].x > a[i].x && a[l].y < a[i].y))
ans[a[i].id] = 1, l = i, cnt++;
cout << cnt << endl;
for(int i = 1; i <= n; i++)
if(ans[i])
cout << i << ' ';
}
⊵⊲⋉⋊D - [cannot be displayed
]
好玩,不会
ɚ▩∀Eɝ - Remove Pairs
问题陈述&分析
十分简单的一个博弈论,我是有考虑暴力搜索,每次暴枚先者选择哪两个,记录这两个已经被选择过,然后向下递归,如果后者作为先者能够必败那我就必胜(因为结果只会是两种:要么赢,要么输[废话] ),否则如果直到每一种情况都遍历过之后仍旧没有后手必败的情况,那么我就必败。
时间复杂度为 O ( n ) O(n) O(n)。
代码
void solve() {
int n;
cin >> n;
int res = 0;
vector<int> a(n), b(n);
for(int i = 0; i < n; i ++)
cin >> a[i] >> b[i];
vector<bool> dp(1 << n, false);
for(int i = 0; i < (1 << n); i ++) {
for(int j = 0; j < n; j ++) {
for(int k = j + 1; k < n; k ++) {
if((i >> j & 1) == 1 && (i >> k & 1) == 1) {
if(a[j] == a[k] || b[j] == b[k]) {
if(!dp[i - (1 << j) - (1 << k)]) {
dp[i] = true;
}
}
}
}
}
}
if(dp[(1 << n) - 1]) {
cout << "Takahashi" << endl;
} else {
cout << "Aoki" << endl;
}
}