ABC287 A~C(C++)
A - Majority
問題概要
ある提案に対し、
人の人が賛成か反対かを表明しています。なお、 N は奇数であることが保証されます。 N
番目の人の意見は文字列 i で表されます。 S_i S_i= For
のときは番目の人が賛成であることを、 i S_i= Against
のときは反対であることを表します。
過半数の人がこの提案に賛成しているか判定してください。
1\leq N\leq 99 -
は奇数N - 各
について、i=1,2,\dots,N S_i= For
またはS_i= Against
問題リンク
解説
実装例
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
int cnt = 0;
for (int i = 0; i < n; i++) {
string s;
cin >> s;
if (s == "For") {
cnt++;
}
}
if (cnt > n / 2)cout << "Yes\n";
else cout << "No\n";
}
B - Postal Card
問題概要
数字のみからなる長さ
の文字列が 6 個与えられます。 N 番目の文字列は i(1\leq i\leq N) です。 S_i
また、数字のみからなる長さの文字列が 3 個与えられます。 M 番目の文字列は i です。 T_i
の末尾 S_i 文字が 3 のいずれかに一致するような T_1,\dots,T_N はいくつありますか? S_i
1\leq N,M\leq 10^3 -
は整数N,M -
であり、|S_i|=6 は数字のみからなるS_i -
であり、|T_i|=3 は数字のみからなるT_i
問題リンク
解説
素直にfor
とかを使うと解ける。
実装例
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<string> s(n), t(m);
for (int i = 0; i < n; i++) {
cin >> s[i];
}
for (int i = 0; i < m; i++) {
cin >> t[i];
}
int ans = 0;
for (int i = 0; i < n; i++) {
bool exist = false;
string sub = s[i].substr(s[i].size() - 3); //末尾3文字
for (int j = 0; j < m; j++) {
if (sub == t[j]) {
exist = true;
}
}
if (exist) {
ans++;
}
}
cout << ans << endl;
}
C - Path Graph?
問題概要
頂点 N 辺の単純無向グラフが与えられます。このグラフがパスグラフであるか判定してください。 M
1\leq N,M\leq 10^5 - 入力はすべて整数
- 入力で与えられるグラフは単純
パスグラフとは
-
なるすべての1\leq i\leq N-1 について、i を結ぶ辺がある。v_i,v_{i+1} -
ならば|i-j|>1 を結ぶ辺はないv_i,v_j
問題リンク
解説(?)
ほぼ木みたいな感じである。ただ、これだけだとダメ。さらに、
- 次数が
以下2
である必要がある。これらの判定は...UnionFindとか使えば解ける。
ACL(AtCoderLibrary)というのがあって、そこにUnionFindは用意されてる。持ってなければ、それを使うといいかも。
筆者の解法(めんどい)
次のように言い換えて解いた。
- 木である。
- ある頂点
が存在して、v を根としてみると各頂点の子は高々v つ1
だと
ちゃんとやると、
あとはDFSとかでがんばる。
実装例
#include<iostream>
#include<atcoder/all>
using namespace std;
using namespace atcoder;
int main() {
int n, m;
cin >> n >> m;
if (m != n - 1) {
cout << "No\n";
return 0;
}
dsu uf(n);
vector<int> deg(n);
for (int i = 0; i < m; i++) {
int v, u;
cin >> v >> u;
v--;
u--;
deg[v]++;
deg[u]++;
if (uf.same(v, u)) {
//サイクルがあったとき
cout << "No\n";
return 0;
}
uf.merge(v, u);
}
if (uf.groups().size() > 1) {
//非連結のとき
cout << "No\n";
return 0;
}
for (int v = 0; v < n; v++) {
//次数が2より大きい頂点があるとき
if (deg[v] > 2) {
cout << "No\n";
return 0;
}
}
cout << "Yes\n";
}
終わりに
D,Eは...別記事で書きます。
ここまで読んでくださってありがとうございます。
Discussion