🔵
【ABC362】AtCoder Beginner Contest 362【C++】
コンテスト名
トヨタ自動車プログラミングコンテスト2024#7(AtCoder Beginner Contest 362)
コンテストURL
開催日
2024/07/13 21:00-22:40
A: Buy a Pen
解法
- 問題文通り
の値によって場合分けして解くC
ABC362A.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
int r, g, b;
cin >> r >> g >> b;
string c;
cin >> c;
if(c=="Red"){
cout << min(g, b) << endl;
}else if(c=="Green"){
cout << min(r, b) << endl;
}else if(c=="Blue"){
cout << min(r, g) << endl;
}
return 0;
}
B: Right Triangle
解法
- ベクトルの内積を考える
- 2 つのベクトルが直交するとき内積は 0 である
-
のうち直交する組み合わせがあるか判定する\overrightarrow{AB}, \overrightarrow{BC}, \overrightarrow{CA} \overrightarrow{AB} = (x_B - x_A, y_B - y_A) \overrightarrow{BC} = (x_C - x_B, y_C - y_B) \overrightarrow{CA} = (x_A - x_C, y_A - y_C)
- 例えば、
のとき、辺\overrightarrow{AB} \cdot \overrightarrow{BC} = (x_B - x_A) \times (x_C - x_B) + (y_B - y_A) \times (y_C - y_B) = 0 と辺AB は直交するBC
ABC362B.cpp
#include <iostream>
using namespace std;
int main(){
int xa, ya, xb, yb, xc, yc;
cin >> xa >> ya >> xb >> yb >> xc >> yc;
int abx = xb - xa, aby = yb - ya;
int bcx = xc - xb, bcy = yc - yb;
int cax = xa - xc, cay = ya - yc;
if(abx*bcx+aby*bcy==0 || bcx*cax+bcy*cay==0 || cax*abx+cay*aby==0){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
return 0;
}
C: Sum = 0
解法
- すべての
について、i = 1, 2, \cdots, N となる場合を考え、足りない分を補充するX_i = L_i -
となるまで各\sum\limits_{i=1}^{N} X_i= 0 に補充するX_i - 最大
の分だけ補充できるR_i - L_i
-
ABC362C.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n;
cin >> n;
vector<long long int> L(n), R(n), D(n);
long long int diffsum = 0, lsum = 0;
for(int i=0; i<n; i++){
cin >> L[i] >> R[i];
lsum += L[i];
D[i] = R[i] - L[i];
diffsum += D[i];
}
if(lsum<=0 && diffsum>=abs(lsum)){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
return 0;
}
for(int i=0; i<n; i++){
if(i){
cout << " ";
}
if(lsum==0){
cout << L[i];
}else if(abs(lsum)>=D[i]){
cout << L[i] + D[i];
lsum += D[i];
}else if(abs(lsum)<D[i]){
cout << L[i] + abs(lsum);
lsum += abs(lsum);
}
}
cout << endl;
return 0;
}
D: Shortest Path 3
解法
- ダイクストラ法
- 辺に重みがある通常のダイクストラ法において、頂点にも重みがある場合を考える
- 頂点
の重みi は、頂点A_i に向かうことが決定したときに加算するi - 辺
を通って頂点j から頂点X に移動するときの頂点Y までの総コストは、頂点Y までのコストX であるとみなす+ B_j + A_{Y}
- 辺
ABC362D.cpp
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
vector<int> A(n);
for(int i=0; i<n; i++){
cin >> A[i];
}
vector<vector<pair<int, int>>> G(n);
int u, v, b;
for(int i=0; i<m; i++){
cin >> u >> v >> b;
u--;
v--;
G[u].emplace_back(v, b);
G[v].emplace_back(u, b);
}
const long long int INF = 1e18;
vector<long long int> dist(n, INF);
priority_queue<pair<long long int, int>, vector<pair<long long int, int>>, greater<pair<long long int, int>>> Q;
dist[0] = A[0];
Q.emplace(A[0], 0);
while(!Q.empty()){
auto [d, now] = Q.top();
Q.pop();
if(dist[now]!=d){
continue;
}
for(int i=0; i<G[now].size(); i++){
auto [next, cost] = G[now][i];
if(d+cost+A[next]>=dist[next]){
continue;
}
dist[next] = d + cost + A[next];
Q.emplace(d+cost+A[next], next);
}
}
for(int i=1; i<n; i++){
if(i-1){
cout << " ";
}
cout << dist[i];
}
cout << endl;
return 0;
}
E: Count Arithmetic Subsequences
解法
- 動的計画法 (DP)
-
:= 初項が\text{dp} [i][k][d] 、長さがA_i 、公差がk である等差数列の場合の数d - 公差
はd から-(10^9 - 1) までとりうるため、10^9 - 1 map<int, long long int>
で管理する - 動的計画法全体は
vector<vector<map<int, long long int>>>
で管理する
- 公差
- 長さ
と長さ1 の等差数列は別途計算することに注意する2
ABC362E.cpp
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main(){
const int MOD = 998244353;
int n;
cin >> n;
vector<int> A(n);
for(int i=0; i<n; i++){
cin >> A[i];
}
vector<vector<map<int, long long int>>> dp(n+1, vector<map<int, long long int>>(n+1));
for(int i=0; i<n; i++){
for(int j=0; j<i; j++){
int d = A[i] - A[j];
for(int k=0; k<=i; k++){
dp[i][k+1][d] += dp[j][k][d]%MOD;
dp[i][k+1][d] %= MOD;
}
dp[i][2][d] += 1;
dp[i][2][d] %= MOD;
}
}
cout << n;
for(int i=2; i<=n; i++){
long long int sum = 0;
for(int j=0; j<n; j++){
for(auto [d, cnt] : dp[j][i]){
sum += cnt%MOD;
sum %= MOD;
}
}
cout << " " << sum;
}
cout << endl;
return 0;
}
Discussion