제목 링크 : https://atcoder.jp/contests/abc188/tasks
A-3 점 슛
이야기
x, y를주고 작은 값에 3을 더한 값이 더 큰 값을 초과 할 수 있는지 묻습니다.
아이디어
직접적인 판단
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
int x, y;
cin >> x >> y;
if(x > y) swap(x, y);
if(x + 3 > y) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
B-직교성
이야기
두 배열, 해당 위치를 곱하고 합하여 0과 같은지 확인합니다.
아이디어
직접 시뮬레이션
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int a[maxn], b[maxn];
int main(){
int n; cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++) cin >> b[i];
ll ans = 0;
for(int i = 1; i <= n; i ++) ans += a[i] * b[i];
if(ans == 0) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
C-ABC 토너먼트
이야기
n과 i 번째 사람의 점수를 나타내는 2 ^ n 개의 숫자를 제공합니다. 각 라운드에는 서로 인접한 2 개의 pk가 있습니다. 점수가 더 높은 사람이 이기고 다음 라운드에 진입하여 이니셜을 출력합니다. 최종 2 위의 아래 첨자
아이디어
벡터 시뮬레이션
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
vector<pair<int, int>> a, b;
int main(){
int n; cin >> n;
for(int i = 1; i <= (1 << n); i ++) {
int x; cin >> x;
a.push_back({x, i});
}
for(int i = 1; i < n; i ++){
for(int j = 0; j < a.size(); j += 2){
if(a[j].first > a[j + 1].first) b.push_back(a[j]);
else b.push_back(a[j + 1]);
}
a = b;
b.clear();
}
if(a[0].first > a[1].first) cout << a[1].second << endl;
else cout << a[0].second << endl;
return 0;
}
D-스 누크 프라임
이야기
Takahashi가 놀러 나가서 지금 n 개의 아이템을 제공합니다. 시간은 [ai, bi]입니다.이 아이템들은 매일 ci를 소비해야하지만,이 날에 나오는 모든 아이템을 재생하기 위해 하루에 C 위안을 소비하도록 선택할 수 있습니다. , 그는 플레이해야하며, 최소한의 지출을 요청해야합니다.
예를 들어, 첫 번째 예에서는 2 개의 항목이 있으며 하루에 나타나는 모든 항목을 재생하는 데 6 개의 비용이 들며, 첫 번째 항목은 [1,2]에 나타나고, 하루에 4 개의 비용이 들며, 두 번째 항목은 [2,2], 4 일당 비용이 발생합니다. 즉, 첫날은 4, 다음날은 4 + 4 = 8을 소비해야하지만 8 <6은 프로젝트 1을 재생하기 위해 6 위안을 소비하도록 선택할 수 있습니다. 2이므로 총 4 + 6 = 10
아이디어
차이점은 당일 각 항목의 비용을 계산하는 것입니다. 그러면 일일 비용은 당일 비용과 C 중 더 작은 값입니다.
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
map<int, ll> mp; // 差分数组
//s表示差分的前缀和,表示到这天单付当天所有项目的花费
//last表示一个天数,(it.first - last)表示s价格出现的天数,也就是在这个期间价格不变
//x表示当天花的钱
//ans表示求的最小花费
int main(){
ll n, c;
cin >> n >> c;
for(int i = 1; i <= n; i ++){
ll x, y, w;
cin >> x >> y >> w;
mp[x] += w; mp[y + 1] -= w; // 差分操作
}
ll s = 0, ans = 0;
int last = 0;
for(auto it : mp){
ll x = min(s, c);
ans += x * (it.first - last);
s += it.second;
last = it.first;
}
cout << ans << endl;
return 0;
}
E-행상
이야기
첫 번째 라인 n, m은 n 개의 점과 m 개의 모서리를 나타냅니다.
두 번째 줄의 n ai는 그 시점의 금 가격을 나타냅니다.
다음 m 개 행은 모서리를 나타내고 각 모서리는 방향 모서리입니다. 여기서 xi는 yi보다 작아야합니다.
이제 그는 금을 사기 위해 한 지점을 선택한 다음 다른 지점으로 가서 금을 팔고 최대 이익을 추구해야합니다.
아이디어
대답은 반복적으로 토폴로지 순서로 나타납니다. dp [i]는 출처 지점 (저는 그 지점을 모릅니다)에서 지점 i까지가는 가장 저렴한 금 가격을 나타냅니다. 단방향 에지이기 때문에 점은 절대로 돌아 가지 않을 것입니다. 실행 후 선형 재귀 만 수행 한 다음 a [son] -dp [i]의 최대 값 만 업데이트하면됩니다. son은 i의 자식 노드입니다.
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
int dp[maxn], in[maxn], a[maxn];
vector<int> v[maxn];
queue<int> q;
int main(){
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i ++) cin >> a[i];
while(m --){
int x, y;
cin >> x >> y;
v[x].push_back(y);
in[y] ++;
}
for(int i = 1; i <= n; i ++){
if(in[i] == 0) q.push(i);
dp[i] = a[i]; //刚开始只初始化入度为0的节点然后wa了7个点,原因是存在2 3, 1 3种情况,也就是说这个图有可能是发散的,必须在跑到他之前就要初始化
}
int ans = -0x3f3f3f3f;
while(q.size()){
int t = q.front(); q.pop();
for(auto it : v[t]){
if(ans == -0x3f3f3f3f || ans < a[it] - dp[t]) ans = a[it] - dp[t];
dp[it] = min(dp[it], dp[t]);
if(--in[it] == 0) q.push(it);
}
}
cout << ans << endl;
return 0;
}
F-+ 1-1x2
이야기
두 개의 숫자 x, y를 주면 매번 각 숫자에 +1 또는 -1 또는 * 2를 수행 할 수 있으며 x를 y로 변경하는 데 필요한 작업 수를 최소한 물어볼 수 있습니다.
아이디어
메모리 검색, dfs (y)는 x를 y로 변경하는 데 필요한 단계 수를 나타냅니다.
구체적으로 코드보기
ac 코드
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
map<ll, ll> dp; //dp[y]表示将x变成y需要的步数
ll x, y;
ll dfs(ll yy){
if(yy <= x) return x - yy; //如果x大于等于yy,那么x只能进行x-yy次 减操作到达yy
if(dp.count(y)) return dp[yy]; //记忆化操作直接返回
ll res = yy - x; //表示x进行yy-x次 加操作到达y
if(yy % 2 == 0) res = min(res, dfs(yy / 2) + 1); //如果yy是偶数,那么就存在乘2的操作,使得x到达yy
else res = min(res, 1 + min(dfs(yy + 1), dfs(yy - 1))); //不然就看看加1减1操作使得x到达yy,取一个最小值
return dp[yy] = res; //记忆化存
}
int main(){
cin >> x >> y;
cout << dfs(y);
return 0;
}