🔵
【ABC356】AtCoder Beginner Contest 356【C++】
コンテスト名
AtCoder Beginner Contest 356
コンテストURL
開催日
2024/06/01 21:00-22:40
A: Subsegment Reverse
解法
- 問題文通りに出力する
-
から1 まではそのままの順(昇順)で出力するL - 1 -
からL は逆順(降順)で出力するR -
からR + 1 はそのままの順(昇順)で出力するN
-
ABC356A.cpp
#include <iostream>
using namespace std;
int main(){
int n, l, r;
cin >> n >> l >> r;
int cnt = 0;
for(int i=1; i<l; i++){
if(cnt){
cout << " ";
}
cnt++;
cout << i;
}
for(int i=r; i>=l; i--){
if(cnt){
cout << " ";
}
cnt++;
cout << i;
}
for(int i=r+1; i<=n; i++){
if(cnt){
cout << " ";
}
cnt++;
cout << i;
}
cout << endl;
return 0;
}
B: Nutrients
解法
- シミュレーションする
-
vector<int>
で各栄養素を管理する
ABC356B.cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
vector<int> A(m);
for(int i=0; i<m; i++){
cin >> A[i];
}
int x;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin >> x;
A[j] -= x;
}
}
for(int i=0; i<m; i++){
if(A[i]>0){
cout << "No" << endl;
return 0;
}
}
cout << "Yes" << endl;
return 0;
}
C: Keys
解法
- bit 全探索でシミュレーションする
-
1
を正しい鍵、0
をダミーの鍵とする -
本の鍵のうち正しい鍵がC_i 本以上ならK R_i = o
、 本未満ならK R_i = x
であるかを判定して、すべての について矛盾しなければ当該組み合わせは条件を満たすi
ABC356C.cpp
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n, m, k;
cin >> n >> m >> k;
vector<vector<int>> A(m);
vector<char> R(m);
int c, a;
for(int i=0; i<m; i++){
cin >> c;
for(int j=0; j<c; j++){
cin >> a;
a--;
A[i].push_back(a);
}
cin >> R[i];
}
int ans = 0;
bool flag;
for(int i=0; i<(1<<n); i++){
flag = true;
for(int j=0; j<m; j++){
int cnt = 0;
for(int l=0; l<A[j].size(); l++){
if(i & (1<<A[j][l])){
cnt++;
}
}
if((cnt>=k && R[j]=='x') || (cnt<k && R[j]=='o')){
flag = false;
}
if(!flag){
continue;
}
}
if(flag){
ans++;
}
}
cout << ans << endl;
return 0;
}
D: Masked Popcount
解法
- 再帰的に求める
- 求める答えを
とおくf(N, M) -
がN ビットで表されるとき、n とおくk = n - 1 - 右上の領域は
\text{popcount} (M \ \text{and} \ (2^k - 1)) \times 2^{k - 1} - 左下の領域は 2 進数表記したときの
のM の桁が2^k ならば1 、N - (2^k - 1) ならば0 0 - 右下の領域は
f(N - 2^k, M)
- 求める答えを
-
1LL
に注意する - 手元で書いて法則を見つける
ABC356D.cpp
#include <iostream>
using namespace std;
const int MOD = 998244353;
int popcnt(long long int x){
int cnt = 0;
while(x){
cnt += x & 1;
x >>= 1;
}
return cnt;
}
int bitlen(long long int x){
int cnt = 0;
while(x){
cnt++;
x >>= 1;
}
return cnt;
}
long long int f(long long int n, long long int m){
if(n==0){
return 0;
}
if(n==1){
return m & 1;
}
int k = bitlen(n) - 1;
long long int a = popcnt(m & ((1LL<<k)-1)) * ((1LL<<(k-1)) % MOD) % MOD;
long long int b;
if(m & (1LL<<k)){
b = (n - ((1LL<<k)-1)) % MOD;
}else{
b = 0;
}
long long int c = f(n - (1LL<<k), m) % MOD;
return (a + b + c) % MOD;
}
int main(){
long long int n, m;
cin >> n >> m;
cout << f(n, m) % MOD << endl;
return 0;
}
参考
Discussion