Link with Equilateral Triangle
d
AC代码:
d
阅读理解题,注意有可能从小于100直接过渡到200+,这个题答案验证是字符串类型,注意只能保留三位小数
AC代码:
#include <bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<n;i++) using namespace std; using LL = long long; void Solve() { int n; cin >> n; vector<double> a(n); for (int i = 0; i < n; i++) { scanf("%lf", &a[i]); } double ans = 0.0; double sum = 0.0; bool ok = false; bool ok1 = false; for (int i = 0; i < n; i++) { if (sum >= 100 && sum < 200) { sum += a[i] * 0.8; } else if (sum >= 200) { sum += a[i] * 0.5; } else { sum += a[i]; } if (!ok) { if (ans + a[i] >= 100 && (a[i] - (100 - ans)) * 0.8 + 100.0 >= 200) { double c = 100 - ans; ans = 100.0; a[i] = 1.0 * a[i] - c; double d = (200.0 - ans); double l = 0.0, r = a[i]; for (int i = 0; i < 50; i++) { double mid = (l + r) / 2; if (mid * 0.8 > d) { r = mid; } else { l = mid; } } ans = 200.0; ans += 1.0 * (a[i] * 1.0 - l) * 0.5; ok = true; ok1 = true; continue; } if (ans + a[i] >= 100) { double c = ans + a[i] - 100; ans = 100.0; ans += 1.0 * c * 0.8; ok = true; } else { ans += a[i]; } } else { if (ans + 1.0 * a[i] * 0.8 >= 200.0 && !ok1) { double d = (200.0 - ans); double l = 0.0, r = 1.0 * a[i]; for (int i = 0; i < 50; i++) { double mid = (l + r) / 2; if (mid * 0.8 > d) { r = mid; } else { l = mid; } } ans = 200.0; ans += 1.0 * (a[i] * 1.0 - l) * 0.5; ok1 = true; } else if (ok1 && ans >= 200) { ans += 0.5 * a[i]; } else { ans += 0.8 * a[i]; } } } printf("%.3lf %.3lf\n", ans, sum); } int main() { int T; scanf("%d", &T); rep (i, 0, T) { Solve(); } return 0; }
因为只能向上跳k步向下跳1步,走过的楼层不能再走,而且要杀死所有怪兽,只能一段一段考虑,否则下面一定有漏掉的怪兽没有打,所以每次攻击力不够了,我们应从能跳到的最远处(或最后一个怪兽的位置,否则RE)且能够打死的怪兽往后枚举,这样保证都能杀死的同时还可以增加攻击力,如果又遇上打不过的,就将攻击力初始化再重复上述操作,直到遇上最开始打不过的怪兽,如果还打不过,那就真打不过了,否则跳到开始增加攻击力的楼层的下一个位置,这个位置要么是跳不到的最近的地方,要么是最初攻击力打不过的地方
这样的暴力竟然比他的标程线段树还快,时间复杂度确实没什么问题
![]()
AC代码:
#include <bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<n;i++) using namespace std; using LL = long long; const int mod = 1e9 + 7; void Solve() { LL n, fi, k; cin >> n >> fi >> k; vector<LL> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { if (a[i] > fi) { int j = i + k - 1; if (i + k - 1 > n) { j = n; } int l = j; LL start = fi; bool ok = false; for (int z = j; z >= i; z--) { if (fi >= a[z]) { fi += a[z]; if (z == i) { ok = true; break; } } else { fi = start; l = z - 1; } } if (ok) { i = l + 1; } else { cout << "NO\n"; return; } } else { fi += a[i]; } } cout << "YES\n"; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; rep (i, 0, T) { Solve(); } return 0; }
标程:
#include<bits/stdc++.h> #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i) #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i) #define ren for(int i=fst[x];i;i=nxt[i]) #define Fill(a,x) memset(a,x,sizeof(a)) using namespace std; typedef long long ll; typedef double db; typedef long double ld; typedef unsigned long long ull; typedef vector<int> vi; typedef pair<int,int> pii; const int inf=2139062143; const int MOD=998244353; const int MAXN=200100; inline int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } inline ll readll() { ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } namespace CALC { inline int pls(int a,int b){return a+b>=MOD?a+b-MOD:a+b;} inline int mns(int a,int b){return a-b<0?a-b+MOD:a-b;} inline int mul(int a,int b){return (1LL*a*b)%MOD;} inline void inc(int &a,int b){a=pls(a,b);} inline void dec(int &a,int b){a=mns(a,b);} inline void tms(int &a,int b){a=mul(a,b);} inline int qp(int x,int t,int res=1) {for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);return res;} inline int Inv(int x){return qp(x,MOD-2);} } using namespace CALC; int n,a[MAXN],k,las,cur,l,r; pair<ll,int> q[MAXN]; ll sum[MAXN],f[MAXN],mxf[MAXN]; ll mn[MAXN<<2]; void build(int k,int l,int r) { if(l==r) {mn[k]=f[l];return ;}int mid=l+r>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); mn[k]=min(mn[k<<1],mn[k<<1|1]); } int res=inf; void query(int k,int l,int r,int a,int b,int w) { if(a<=l&&r<=b) { if(mn[k]>w||res!=inf) return ; if(l==r) {res=l;return ;}int mid=l+r>>1; if(mn[k<<1]<=w) query(k<<1,l,mid,a,b,w); else if(mn[k<<1|1]<=w) query(k<<1|1,mid+1,r,a,b,w); return ; } int mid=l+r>>1; if(a<=mid) query(k<<1,l,mid,a,b,w); if(b>mid) query(k<<1|1,mid+1,r,a,b,w); } int solve() { n=read(),a[0]=sum[0]=read(),k=min(read(),n); rep(i,1,n) a[i]=read(),sum[i]=sum[i-1]+a[i]; f[0]=sum[0]<<1;rep(i,1,n) f[i]=max(sum[i]+a[i],f[i-1]); rep(i,0,n) f[i]=f[i]-sum[i]; //rep(i,0,n) cout<<f[i]<<" ";puts(""); build(1,1,n); las=-1,cur=0; while(cur!=n) { res=inf; query(1,1,n,cur+1,min(las+k+1,n),sum[cur]); //cout<<las<<" "<<cur<<" "<<res<<endl; if(res==inf) return 0; las=cur,cur=res; } return 1; } int main() { rep(T,1,read()) puts(solve()?"YES":"NO"); }
线性基板板题,从这 个数里任取一些数异或起来的方案,都是可以构造出对应的操作来 做到的,问题完全等价于给n个数,从中选一些数,使得这些数的异或和最大。
AC代码:
#include <bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<n;i++) using namespace std; using LL = long long; const int mod = 1e9 + 7; void Solve() { int n; cin >> n; vector<LL> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } int k = 0; for (int i = 62; i >= 0; i--) { for (int j = k; j < n; j++) { if (a[j] >> i & 1) { swap(a[j], a[k]); break; } } if (!(a[k] >> i & 1)) { continue; } for (int j = 0; j < n; j++) { if (j != k && (a[j] >> i & 1)) { a[j] ^= a[k]; } } k++; if (k == n) { break; } } LL ans = 0; for (int i = 0; i < k; i++) { ans ^= a[i]; } cout << ans << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; rep (i, 0, T) { Solve(); } return 0; }
2022“杭电杯”中国大学生算法设计超级联赛(4)D、F、G、K
于 2022-08-02 10:59:58 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)