A. 神話キャラクター
解決アプローチ:各要素についてソート後の隣接要素を確認します。二分探索により位置を特定し、左右の値が条件を満たすか判定します。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define YES(x) (x ? "Yes" : "No")
const int MOD = 1e9 + 7;
int main_val[100005], backup_val[100005];
void process() {
int N, count = 0;
cin >> N;
for(int i=0; i<N; i++) {
cin >> main_val[i];
backup_val[i] = main_val[i];
}
sort(main_val, main_val+N);
for(int i=0; i<N; i++) {
int X;
cin >> X;
int pos = lower_bound(main_val, main_val+N, backup_val[i]) - main_val;
if((pos>0 && main_val[pos-1] >= backup_val[i]-X) ||
(pos<N-1 && main_val[pos+1] <= backup_val[i]+X)) continue;
count++;
}
cout << count << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
process();
return 0;
}
B. ソーシャルネットワーク
数学的アプローチ:各ノードの友人関係を解析します。度数計算により効率的に処理し、最適化された方法で結果を導出します。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 200005;
vector<int> connections[MAXN];
int node_degree[MAXN];
void analyze() {
int N;
cin >> N;
for(int i=1; i<N; i++) {
int u, v;
cin >> u >> v;
connections[u-1].push_back(v-1);
connections[v-1].push_back(u-1);
node_degree[u-1]++;
node_degree[v-1]++;
}
for(int i=0; i<N; i++) {
int result = 0;
for(auto neighbor: connections[i]) {
result += connections[neighbor].size() - 1;
}
cout << result << ' ';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
analyze();
return 0;
}
C. 結婚式の準備
最適化戦略:伴郎/伴娘の配置を差分に基づいてソートし、優先度付きキューを活用した効率的な選定を行います。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 200005;
int value_a[MAXN], value_b[MAXN];
priority_queue<int, vector<int>, greater<>> pq;
vector<int> sorted_indices;
void calculate() {
int N, M;
cin >> N >> M;
for(int i=0; i<N+M+1; i++) cin >> value_a[i];
for(int i=0; i<N+M+1; i++) {
int b;
cin >> b;
value_a[i] -= b;
sorted_indices.push_back(i);
}
sort(sorted_indices.begin(), sorted_indices.end(), [&](int x, int y){
return value_a[x] > value_a[y];
});
ll total_sum = 0, selected_sum = 0;
for(int i=0; i<N; i++) selected_sum += value_a[sorted_indices[i]];
for(int i=0; i<N+M+1; i++) {
if(i < N) {
cout << total_sum - b[sorted_indices[i]] + selected_sum - value_a[sorted_indices[i]] + value_a[sorted_indices[N]] << ' ';
} else {
cout << total_sum - b[sorted_indices[i]] + selected_sum << ' ';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
calculate();
return 0;
}
D. 再会の確率
動的計画法アプローチ:各ステップでの状態遷移を前計算し、範囲指定に基づく効率的な合計計算を実行します。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1e9 + 7;
const int MAXN = 100005;
ll dp[MAXN];
void solve() {
int target, step;
cin >> target >> step;
dp[0] = 1;
for(int i=1; i<=target; i++) {
int low = max(0, i-step);
dp[i+1] = (dp[low] + dp[i]) % MOD;
}
cout << dp[target+1] << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
E. 城市探索
木構造の最適化:子ノードの情報を辞書木形式で管理し、ビット単位でのマッチング処理を実行します。葉ノードの特殊処理を考慮します。