题目链接 https://atcoder.jp/contests/abc153/tasks/abc153_f
题意 : 在坐标轴上有一些怪兽,每个怪兽有对应的生命值hi,你可以对他们进行炮击,你的每次炮击可以队该点前后D范围内的怪兽造成A的伤害,问最少要炮击多少次。
我的最初的想法是先排序,扫到最左边的怪兽,先进行炮击,把他打死,然后记录炮击了多少次,然后把其后2d距离的怪兽都炮击一下发现超时
代码如下:
inline ll read(){ ll s=0,w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar(); return s*w; } const int N = 2e5+5; struct mon { ll x,h; }; mon monster[N]; bool cmp(mon a, mon b) { return a.x < b.x; } int main() { //ios::sync_with_stdio(false);cin.tie(NULL); ll n, d, a; n = read(); d = read(); a = read(); for (int i = 0; i < n; i++) { monster[i].x = read(); monster[i].h= read(); } sort(monster, monster + n,cmp); ll ans = 0; for (int i = 0; i < n; i++) { if (monster[i].h>0) { ll xx = monster[i].x + d; ll num = (monster[i].h + a - 1) / a; ans += num; monster[i].h = 0; bool flag = false; for (int j = i + 1; monster[j].x >= (xx - d) && monster[j].x<= xx + d && j < n;j++) { monster[j].h-=a*num; } } } cout << ans << endl; }
后来学习了大佬的代码,他是这么操作的,建立一个数组c[i],记录每个点已经炮击了几次need,则c[i] += need,下一个点已经炮击的次数就是c[i + 1] += c[i],因为范围外就无效,所以每个点i你要先找到他最远能打到哪里,然后要事先减掉need,即c[j] -= need; 这样,当i到了j-1时,执行c[i+1] += c[i], need正好抵消,我觉得这个技巧太妙了
代码:
#include<iostream> #include<string> #include <cstdlib> #include <algorithm> #include<cmath> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<map> #include<set> #include<bitset> #include <iomanip> // #pragma comment(linker, "/STACK:1024000000,1024000000") // #define pi acos(-1) // #include<bits/stdc++.h> using namespace std; typedef long long ll; #define INF 0x7f7f7f7f //2139062143 #define INF1 0x3f3f3f3f //1061109567 #define INF2 2147483647 #define llINF 9223372036854775807 #define pi 3.141592653589793//23846264338327950254 #define pb push_back #define ll long long #define debug cout << "debug\n"; // freopen(".in","r",stdin); // freopen(".out","w",stdout); // ios::sync_with_stdio(false);cin.tie(NULL); #define scai(x) scanf("%d", &x) #define sca2i(x, y) scanf("%d %d", &x, &y) #define scaf(x) scanf("%lf", &x) #define sca2f(x, y) scanf("%lf %lf", &x, &y) #define For(m,n) for (int i = m; i < n; i++) #define local #ifdef local #endif #define MAX 10233 #define LCH(i) ((i) << 1) #define RCH(i) ((i) << 1 | 1) inline ll read(){ ll s=0,w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar(); return s*w; } const int N = 2e5+5; ll c[N]; struct mon { ll x,h; }; mon monster[N]; bool cmp(mon a, mon b) { return a.x < b.x; } int main() { //ios::sync_with_stdio(false);cin.tie(NULL); // cout << 50ll << endl; ll n, d, a; n = read(); d = read(); a = read(); for (int i = 0; i < n; i++) { monster[i].x = read(); monster[i].h= read(); } sort(monster, monster + n,cmp); ll ans = 0; for (int i = 0,j = 0; i < n; i++) { while(j < n && monster[j].x <=monster[i].x + 2*d) ++j; ll need = max((monster[i].h - c[i]*a + a - 1)/a, 0ll); ans += need; c[i] += need; c[j] -= need; c[i+1] += c[i]; } cout << ans << endl; }
原文地址:https://www.cnblogs.com/hulian425/p/12236097.html
时间: 2024-11-06 12:30:28