感觉这场都是猜,补了个D
A - Profitable Interest Rate
思路
给定a和b,一次a减去1,b减去2,问什么时候,a>b
实际上就是a-x>=b-2x,也就是x>=b-a
代码
void solve() {
int a, b;
cin >> a >> b;
// a-x>=b-2*x
// x>=b-a;
ll x=b-a;
if(b<=a){
cout<<a;
return;
}
ll c = 0;
cout << max(c, a-(b - a));
}
B- Buying Lemonade
思路
通过他给的案例我们会发现,实际上就是从1到n开始点击,一遍一遍的循环,如果当前点点击了一下没有之后就不点击了,那么排序之后从小的开始点击,知道点击到>=k为止
代码
void solve() {
ll n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
arr[i];
}
sort(arr + 1, arr + 1 + n);
ll sum=0;
for(int i=1;i<=n;i++){
if(sum+arr[i]*(n-i+1)>=k){
cout<<i-1+k;
return;
}
sum=sum+arr[i];
}
}
C - Concatenation of Arrays
思路
其实不是很会猜的,按样例跑一边,发现是和的小的在前面,就结束了,证明可以看官网的题解
代码
struct node {
ll x, y;
};
node arr[200020];
bool cmp(node a, node b) {
if(a.x+a.y!=b.x+b.y){
return a.x+a.y<b.x+b.y;
}
if (a.x != b.x) {
return a.x < b.x;
}
return a.y < b.y;
}
void solve() {
ll n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> arr[i].x >> arr[i].y;
}
sort(arr + 1, arr + 1 + n, cmp);
for (int i = 1; i <= n; i++) {
cout << arr[i].x << " " << arr[i].y << ' ';
}
}
D - Skipping
思路
赛时想用dp写的,发现一直不对,发现最短路,我们发现,如果从i到b[i]需要代价为a[i],所以我们会发现,从点i到i-1放一条边权为0的有向路,那么i到b[i]需要的是价值为a[i]的边权路,求最短路即可
代码
struct edge {
int v, w;
};
struct node {
int dis, u;
bool operator>(const node& a) const {
return dis > a.dis;
}
};
const int MAXN = 4e5+2;
vector<edge> e[MAXN];
int dis[MAXN], vis[MAXN];
priority_queue<node, vector<node>, greater<node>> q;
void dijkstra(int n, int s) {
memset(dis, 0x3f, (n + 1) * sizeof(int));
dis[s] = 0;
q.push({ 0, s });
while (!q.empty()) {
int u = q.top().u;
q.pop();
if (vis[u]) {
continue;
}
vis[u] = 1;
for (auto ed : e[u]) {
int v = ed.v, w = ed.w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push({ dis[v], v });
}
}
}
}
void solve() {
ll n;
cin >> n;
vector<ll>arr(n + 2);
vector<ll>brr(n + 2);
for (int i = 1; i <= n; i++) {
cin >> arr[i];
vis[i] = 0;
e[i].clear();
}
for (int i = 1; i <= n; i++) {
cin >> brr[i];
e[i].push_back({ i - 1,0 });
e[i].push_back({ brr[i],arr[i] });
}
dijkstra(n, 1);
/*for (int i = 1; i <= n; i++) {
cout << dis[i] << " ";
}*/
ll ans = 0;
ll sum = 0;
for (int i = 1; i <= n; i++) {
sum = sum + arr[i];
if (dis[i] != 0x3f) {
ans = max(ans, sum - dis[i]);
}
}
cout << ans;
}