练习记录-河南2020省赛补题(ABCE)
A 班委竞选
比手速直接写掉了(
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; struct stu{ int id,zw,p; }S[MAXN]; bool bj(stu a,stu b){ if(a.zw!=b.zw) return a.zw<b.zw; else if(a.p!=b.p) return a.p>b.p; else return a.id<b.id; } void solve(){ int n,m;cin>>n>>m; for(int i=1;i<=n;i++){ cin>>S[i].zw>>S[i].p; S[i].id=i; } sort(S+1,S+n+1,bj); int cnt=1; for(int i=1;i<=n;i++){ if(S[i].zw==cnt) { cout<<S[i].id<<" "; cnt++; } } } int main(){ solve(); }
B 广告投放(dp)
这是补的 考场上太慌,转移方程写的一拖四,根本写不出来
考后看了别人的代码,应该以人数作为转移方程的i值,由于转移只会用到上一层,用01数组可以优化
转移方程:dp[i%2][c[j]]=max(dp[i%2][c[j]],dp[(i-1)%2][c[j]]) 表示不在这集播广告的状态
dp[i%2][c[j]/w[i]]=max(dp[i%2][c[j]/w[i]],dp[(i-1)%2][c[j]]+v[i]*c[j]) 表示在这集播广告的状态
其中 c[i]为处理后的人数数组 如果直接遍历m 会超时 而m经过整除 只会到达某几个数 如5 无法到达3和4 因此可以通过处理减少计算次数
然后就好了
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; #define int long long int vis[MAXN],dp[2][MAXN],c[MAXN],v[MAXN],w[MAXN]; int lowbit(int x){ return x&-x; } int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>v[i]; for(int i=1;i<=n;i++) cin>>w[i]; //处理人数的可能性减小计算次数 //使用01数组优化 int cnt=0; c[++cnt]=0; //处理出所有的可能性 大幅降低时间 for(int i=1;i<=m;i++){ if(!vis[m/i]){ vis[m/i]=1; c[++cnt]=m/i; } } //sort(c+1,c+1+cnt); for(int i=1;i<=n;i++){ for(int j=1;j<=cnt;j++){ dp[i%2][c[j]]=max(dp[i%2][c[j]],dp[(i-1)%2][c[j]]);//从原始数据转移 dp[i%2][c[j]/w[i]]=max(dp[i%2][c[j]/w[i]],dp[(i-1)%2][c[j]]+v[i]*c[j]); //处理选择后的数据 } } int ans=0; for(int i=0;i<=m;i++) ans=max(ans,dp[n%2][i]); cout<<ans; } signed main(){ close; solve(); }
C 我得重新集结部队
模拟 就直接模拟就行了 但是要注意 不要拿sqrt算距离 直接ll算平方和,不然会出现精度问题 wa11个样例
我是拿sort排序自带算出距离最小的 第一次这么写sort的函数 没想到真的可以
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; const double eps =1e-6; #define int long long struct muxi{ int x,y,h,id,die; }M[MAXN]; int xx,yy,ans[MAXN]; bool bj(muxi a,muxi b){ int ax=a.x,ay=a.y,bx=b.x,by=b.y; ll disa=(ax-xx)*(ax-xx)+(ay-yy)*(ay-yy); ll disb=(bx-xx)*(bx-xx)+(by-yy)*(by-yy); if(a.h<=0||b.h<=0){ return a.h>b.h; } else if(disa!=disb){ return disa<disb; } else return a.id<b.id; } int cnt=0; void solve(){ int n;cin>>n; for(int i=1;i<=n;i++){ int op;cin>>op; if(op==1){ int x,y,h; cin>>x>>y>>h; M[cnt].id=i;M[cnt].h=h,M[cnt].x=x,M[cnt].y=y; cnt++; } else{ int r,atk; cin>>xx>>yy>>atk>>r; sort(M,M+cnt,bj); int ax=M[0].x,ay=M[0].y; int flag=0; for(int j=0;j<cnt;j++){ int bx=M[j].x,by=M[j].y; if((ax-bx)*(ax-bx)+(ay-by)*(ay-by)<=1LL*r*r){ if(M[j].h>0) M[j].h-=atk*3; if(M[j].h>0) ans[i]=1; else ans[M[j].id]=1; } } } } for(int i=1;i<=n;i++){ if(ans[i]==1) cout<<"NO\n"; else cout<<"YES\n"; } } signed main(){ solve(); }
E 发通知
补的 考场上一直拿区间相交在模拟 但是这题对于每一个线段,从1-1e9遍历 遇到头节点就^w,遇到尾节点再异或一遍 因此把每个点首位拆开进行排序 然后记录点的了,类型
遍历所有的点 记录ans与cnt cnt>=k就取max 即可得出答案
还要注意如果有同一点的 要先一起处理完再计算
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 2e6+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; int f[MAXN]; struct node{ int t,w,x; }N[MAXN]; bool bj(node a,node b){ return a.x<b.x; } int lowbit(int x){ return x&-x; } int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ int n,m;cin>>n>>m; for(int i=0;i<n;i++){ int x,y,w;cin>>x>>y>>w; N[i*2].x=x,N[i*2].t=1,N[i*2].w=w; N[i*2+1].x=y+1,N[2*i+1].t=-1,N[i*2+1].w=w; } map<int,int> sz; sort(N,N+2*n,bj); int maxs=-1,ans=0,cnt=0; for(int i=0;i<2*n;i++){ cnt+=N[i].t; ans^=N[i].w; if(cnt>=m&&N[i].x!=N[i+1].x) maxs=max(ans,maxs); } cout<<maxs; } int main(){ solve(); }
后续继续补题将更新

浙公网安备 33010602011771号