問題Dの解法
整数配列Aが与えられたとき、他の全ての要素で割り切れない要素の数を求める問題です。配列サイズは最大2×10^5です。
解法としては、各数値の出現頻度を記録し、各要素の約数を調べて他の要素で割り切れるか判定します。重複要素がある場合に注意が必要です。
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e6+5;
int main() {
int n;
cin >> n;
vector<int> nums(n);
vector<int> freq(MAX, 0);
for(int i=0; i<n; i++) {
cin >> nums[i];
freq[nums[i]]++;
}
int cnt = 0;
for(auto num : nums) {
if(freq[num] > 1) {
cnt++;
continue;
}
bool divisible = false;
for(int d=1; d*d<=num; d++) {
if(num%d == 0) {
if((d!=num && freq[d]) || (d!=1 && freq[num/d])) {
divisible = true;
break;
}
}
}
if(!divisible) cnt++;
}
cout << cnt << endl;
return 0;
}
問題Eの解法
要素の集合移動とクエリ処理を行う問題です。優先度付きキューを使用して効率的に処理します。
#include<bits/stdc++.h>
using namespace std;
using pii = pair<int,int>;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<priority_queue<pii>> groups(2e5+1);
priority_queue<pii, vector<pii>, greater<>> min_heap;
vector<int> values(n+1), locations(n+1);
for(int i=1; i<=n; i++) {
int a, b;
cin >> a >> b;
values[i] = a;
locations[i] = b;
groups[b].emplace(a, i);
}
for(int i=1; i<=2e5; i++) {
if(!groups[i].empty()) {
min_heap.emplace(groups[i].top().first, i);
}
}
while(q--) {
int c, d;
cin >> c >> d;
int src = locations[c];
while(!groups[src].empty() &&
(locations[groups[src].top().second] != src ||
groups[src].top().second == c)) {
groups[src].pop();
}
if(!groups[src].empty()) {
min_heap.emplace(groups[src].top().first, src);
}
locations[c] = d;
groups[d].emplace(values[c], c);
min_heap.emplace(groups[d].top().first, d);
while(min_heap.top().first != groups[min_heap.top().second].top().first) {
min_heap.pop();
}
cout << min_heap.top().first << '\n';
}
return 0;
}
問題Fの解法
グリッド上の最短経路問題で、1回の移動で最大kマス移動可能です。BFSを使用し、効率化のために訪問済みチェックを最適化します。
#include<bits/stdc++.h>
using namespace std;
const int INF = 1e9;
struct Position {
int x, y;
};
int main() {
int h, w, k, sx, sy, ex, ey;
cin >> h >> w >> k >> sx >> sy >> ex >> ey;
vector<string> grid(h);
for(int i=0; i<h; i++) cin >> grid[i];
vector<vector<int>> dist(h, vector<int>(w, INF));
queue<Position> q;
q.push({sx-1, sy-1});
dist[sx-1][sy-1] = 0;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
while(!q.empty()) {
auto curr = q.front(); q.pop();
for(int dir=0; dir<4; dir++) {
for(int step=1; step<=k; step++) {
int nx = curr.x + step*dx[dir];
int ny = curr.y + step*dy[dir];
if(nx<0 || nx>=h || ny<0 || ny>=w || grid[nx][ny]=='@') break;
if(dist[nx][ny] < dist[curr.x][curr.y]+1) break;
if(dist[nx][ny] > dist[curr.x][curr.y]+1) {
dist[nx][ny] = dist[curr.x][curr.y]+1;
q.push({nx, ny});
}
}
}
}
cout << (dist[ex-1][ey-1]==INF ? -1 : dist[ex-1][ey-1]) << endl;
return 0;
}