A.小红打怪
显然每次攻击 总次数最小,即答案为
。
a, l, r = map(int, input().split())
print((a+r-1)//r)
B.小红砍怪
注意到只能攻击一次,因此答案为相同的两个数之间的最远距离。
n = int(input())
a = [0] + list(map(int, input().split()))
p = [0 for _ in range(n+1)]
ans = 0
for i in range(1, 2*n+1):
if not p[a[i]]:
p[a[i]] = i
else:
ans = max(i - p[a[i]] + 1, ans)
print(ans)
C.小红加强打怪
显然,对同一个目标连续攻击到消灭为止最优。
对同一个目标连续攻击 次后,总伤害为
。
可以用二分求出每个的最小次数。
n = int(input())
a = list(map(int, input().split()))
ans = 0
for i in a:
l = 1
r = 10**18
tans = -1
while l <= r:
mid = (l + r)>>1
if mid*(mid+1)//2 >= i:
tans = mid
r = mid - 1
else:
l = mid + 1
ans += tans
print(ans)
D.小红走迷宫
dfs 或者 bfs 遍历整张图即可。
void solve(){
ll n = read(), m = read(), x = read();
vector<ll> f(n+1);
for(ll i=1;i<=x;i++) f[read()] = 1;
vector<ll> vis(n+1);
vector<vector<ll>> g(n+1);
for(ll i=1,u,v;i<=m;i++){
u = read(), v = read();
g[u].pb(v);
g[v].pb(u);
}
function<void(ll, ll)> dfs = [&](ll u, ll p){
vis[u] = 1;
for(auto v:g[u]){
if(v!=p&&!vis[v]&&!f[v]){
dfs(v, u);
}
}
};
dfs(1, 0);
for(ll i=1;i<=n;i++){
if(vis[i]) pt(i),putchar(' ');
}
}
E.小苯的刷怪笼
每次攻击最多使得奇数位上的数字 ,偶数位上的数字
,因此不难得出对一个序列
,最小攻击次数为奇数位之和和偶数位之和的最小值,因此
。
同时,因为小红一定优先两两攻击,则我们让除了第一个数之外全是 ,最多可以让小红攻击
次。
因此 满足
,否则为
。
我们只要让奇数位之和为 ,偶数位之和为
即可。
注意特判 。
void solve(){
ll n = read(), a = read(), k = read();
if(n == 1){
if(a == k){
print(a);
}
else{
print(-1);
}
return;
}
if(!((a+1)/2<=k&&k<=(a-n/2))){
print(-1);
return ;
}
vector<ll> ans(n, 1);
ans[0] += k - (n+1)/2;
ans[1] += (a-k) - (n/2);
print(ans);
}
F.毒苯
不难想到用并查集模拟,但是在线写时间复杂度 。如果预处理了空间复杂度至少
(
个并查集)。
因此考虑离线处理。
我们从小大大排列所有点和询问。对每个询问 把所有值不超过
的点加入并查集并与四周链接。
注意我们没法每次询问都找一遍第一行的元素(个人感觉每次找一遍容易卡常),因此对每个连通分量我们要记录其与第一行有没有链接,并且每次链接点的时候记录变化值。
class DSU{
public:
vector<ll> parent, size, flag;
DSU(ll n){
parent.resize(n+1);
size.resize(n+1, 1);
flag.resize(n+1);
for(ll i=1;i<=n;i++) parent[i] = i;
}
ll find(ll p){
if(parent[p]!=p)parent[p]=find(parent[p]);
return parent[p];
}
ll unite(ll u, ll v){
u = find(u), v = find(v);
if(u == v) return 0;
if(size[u]<size[v]) swap(u, v);
ll pre = flag[u] * size[u] + flag[v] * size[v];
parent[v] = u;
size[u] += size[v];
flag[u]|=flag[v];
ll now = flag[u] * size[u];
return now - pre;
}
};
vector<PLL> d = {{1, 0}, {-1, 0}, {0, -1},{0, 1}};
void solve(){
ll n = read(), m = read(), q = read();
vector<vector<ll>> a(n+1, vector<ll>(m+1));
vector<PLL> ps;
ll idx = 1;
auto trans = [&](ll x, ll y){
return (x-1) * m + y;
};
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
a[i][j] = read();
ps.pb({a[i][j], trans(i, j)});
}
}
vector<PLL> qs;
vector<ll> ans(q);
for(ll i=0;i<q;i++){
qs.pb({read(), i});
}
DSU dsu((n+2)*(m+2));
for(ll y=1;y<=m;y++) dsu.flag[trans(1, y)] = 1;
sort(all(qs));
sort(all(ps));
ll idxp = 0;
ll res = 0;
vector<vector<ll>> vis(n+2, vector<ll>(m+2));
for(auto [qx, idx]:qs){
while(idxp<ps.size()&&ps[idxp].fi<=qx){
ll x = (ps[idxp].se-1)/m + 1, y = (ps[idxp].se-1) % m + 1;
vis[x][y] = 1;
if(x == 1) res++;
for(auto [dx, dy]:d){
ll nx = x + dx, ny = dy + y;
if(1<=nx&&nx<=n&&1<=ny&&ny<=m&&a[nx][ny]<=qx&&vis[nx][ny]){
res += dsu.unite(ps[idxp].se, trans(nx, ny));
}
}
++idxp;
}
ans[idx] = res;
}
for(ll i=0;i<q;i++) print(ans[i]);
}