A题
贪心从10开始
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; const int mod=1e9+7; int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ ll a,b; cin>>a>>b; if(a>b){ swap(a,b); } int cnt=0; b-=a; for(int i=10;i>=1;i--){ if(b==0) break; cnt+=b/i; b%=i; } cout<<cnt<<endl; } return 0; }
B题
贪心
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=2e5+10; const int M=2e6+10; const int inf=0x3f3f3f3f; const ll mod=998244353; int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ ll a,b,c,d,n,x,y; cin>>a>>b>>c>>d>>n; ll ans=1e18; x=a-c,y=b-d; ll dd=n; ll tmp1=a-min(n,x); dd-=min(n,x); ll tmp2=b-min(dd,y); ans=min(ans,tmp1*tmp2); dd=n; tmp1=b-min(n,y); dd-=min(n,y); tmp2=a-min(dd,x); ans=min(ans,tmp1*tmp2); cout<<ans<<endl; } return 0; }
C题
我采用的方法是找到差值的因数,从小到大枚举,看看能否达到50个
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e6+10; const int mod=1e9+7; vector<int> num; int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n,x,y; cin>>n>>x>>y; if(x==y){ int i; for(i=1;i<=n;i++) cout<<x<<" "; cout<<endl; continue; } int tmp=y-x; int flag=0; for(int i=1;i<=tmp;i++){ if(tmp%i==0){ num.clear(); int cnt=x; num.push_back(x); num.push_back(y); if((n-1)*i<tmp) continue; if(num.size()==n){ flag=1; break; } while(cnt+i<y&&num.size()<n){ num.push_back(cnt+i); cnt+=i; } if(num.size()==n){ flag=1; break; } if(num.size()>n){ break; } cnt=x; while(cnt-i>=1&&num.size()<n){ num.push_back(cnt-i); cnt-=i; } if(num.size()==n){ flag=1; break; } if(num.size()>n){ break; } cnt=y; while(num.size()<n){ num.push_back(cnt+i); cnt+=i; } if(num.size()==n){ flag=1; break; } if(num.size()>n){ break; } } if(flag) break; } sort(num.begin(),num.end()); for(auto x:num){ cout<<x<<" "; } cout<<endl; } return 0; }
D题
答案一定是后面跟着一串0,因此从低位往上做即可
E题
枚举+二分+后缀最大值,我们只暴力x,然后排序。
因为只有两个,因此常见的套路就是枚举第一个做第二个,第一个做了之后,就是找第一个不能覆盖的位置取一个最大值
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const int mod=1e9+7; int a[N],b[N]; vector<int> num; map<int,int> m1; int d[N]; int id[N]; struct node{ int l,r; int mx; }tr[N<<2]; void pushup(int u){ tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx); } void build(int u,int l,int r){ if(l==r){ tr[u]={l,r,0}; } else{ tr[u]={l,r}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); pushup(u); } } void modify(int u,int l,int x){ if(tr[u].l==tr[u].r){ tr[u].mx+=x; return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,x); else modify(u<<1|1,l,x); pushup(u); } int query(int u,int l,int r){ if(tr[u].l>=l&&tr[u].r<=r){ return tr[u].mx; } int mid=tr[u].l+tr[u].r>>1; int ans=0; if(l<=mid) ans=query(u<<1,l,r); if(r>mid) ans=max(ans,query(u<<1|1,l,r)); return ans; } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n,k; cin>>n>>k; int i; m1.clear(); num.clear(); for(i=1;i<=n;i++){ cin>>a[i]; num.push_back(a[i]); } for(i=1;i<=n;i++) cin>>b[i]; sort(a+1,a+1+n); build(1,1,n+1); for(i=1;i<=n;i++){ if(!m1[a[i]]){ m1[a[i]]=i; } } sort(num.begin(),num.end()); for(i=1;i<=n;i++){ int x=a[i]; x+=k; if(num[num.size()-1]<x){ d[i]=n-i+1; id[i]=n+1; } int pos=upper_bound(num.begin(),num.end(),x)-num.begin()+1; d[i]=pos-i; id[i]=pos; } for(i=1;i<=n;i++){ modify(1,i,d[i]); } int ans=0; for(i=1;i<=n;i++){ int x=query(1,id[i],n+1); ans=max(ans,d[i]+x); } cout<<ans<<endl; } return 0; }
F题
因为要算贡献,且每个位置只有三种变化,不变,变1,变2,因此我们设计状态为前i个,有j个t1,用了k次的最大值
注意特判t1==t2的情况
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const int mod=1e9+7; ll f[210][210][210]; int main(){ ios::sync_with_stdio(false); string s,t; int n,m; cin>>n>>m; cin>>s>>t; int i,j,k; s=" "+s; t=" "+t; memset(f,-0x3f,sizeof f); f[0][0][0]=0; if(t[1]==t[2]){ int ans=0; for(i=1;i<=n;i++){ if(s[i]==t[1]){ ans++; } } int d=n-ans; d=min(m,d); ans+=d; if(!ans) cout<<0<<endl; else cout<<ans*(ans-1)/2<<endl; return 0; } for(i=1;i<=n;i++){ for(j=0;j<=i;j++){ for(k=0;k<=min(m,i);k++){ if(s[i]==t[1]){ if(j) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]); if(k) f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j); } else if(s[i]==t[2]){ if(j&&k) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]); f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+j); } else{ f[i][j][k]=f[i-1][j][k]; if(k){ if(j) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]); f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j); } } } } } ll ans=0; for(i=0;i<=n;i++){ for(j=0;j<=m;j++){ ans=max(ans,f[n][i][j]); } } cout<<ans<<endl; return 0; }