23 暑假友谊赛 No.3
23 暑假友谊赛 No.3
A - 把你砍成两半!
思路:确定a1时,当a2~an都为a1的倍数时,条件一定满足
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int ans=0,n,k;cin>>n>>k; for(int i=1;i<=n;++i){ if(n/i>=k)ans=(ans+Lucas(n/i-1,k-1))%mod; } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); //cin>>t; while(t--){ solve(); } return 0; }
B - 小叶,我们加油!
思路:暴力求每一行选每种方案的最小价值,或对每一行dp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; vector<int>C; void init(){ } void solve(){ int n,m,x,y;cin>>n>>m>>x>>y; int a=0,b=0; string s; for(int i=0;i<n;++i){ cin>>s; s.insert(0,"*");s.push_back('*'); for(int j=1;j<=m;++j){ if(s[j]=='.'){ if(s[j-1]=='*'&&s[j+1]=='*')a++,s[j]='*'; else if(s[j+1]=='.'){ if(y<=2*x)b++; else a+=2; s[j]=s[j+1]='*';j++; } } } } cout<<a*x+b*y<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; init(); while(T--){ solve(); } return 0; }
C - 工程学的作用不可小觑!
思路:取两个边界即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void solve(){ PII ve[2],a[2]; for(int i=0;i<2;++i){ cin>>ve[i].first>>ve[i].second;a[i]=ve[i]; } sort(ve,ve+2); if(ve[0].first==a[0].first&&ve[0].second==a[0].second) cout<<ve[0].first<<' '<<ve[1].second<<'\n'; else cout<<ve[1].second<<' '<<ve[0].first<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; while(T--){ solve(); } return 0; }
D - 做博士的护卫?好哦。
思路:
由两个等式可以推出c=b+1,a2=2b-1<=2n-1,即a<=√2n-1,且a为奇数;
枚举所有的a,即可知道所有的b、c;二分求出n以内的c的个数即可
E - 暴虐的恶人阻断正义的道路,我的主人啊,以复仇与恶意为名,引领弱小的人把。
思路:出现次数最大的数即为答案
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void solve(){ int n;cin>>n; vector<int>cnt(105,0); int ans=0; for(int i=0,x;i<n;++i){ cin>>x; cnt[x]++; ans=max(ans,cnt[x]); } cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //cin>>T; while(T--){ solve(); } return 0; }
F - 我才不会一个人的时候跟仿生海龙聊天!
思路:f[i][j]表示第i种菜选择j的最小代价,f[i][j]=f[i-1][k]+a[i][j],其中(k,j)可搭配;
用multiset维护f[i-1][j]的最小值,枚举第i种菜的每个j,将不能与j搭配的菜删掉,计算完f[i][j]后将删去的菜加回来
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ vector<int>n(4); for(int i=0;i<4;++i)cin>>n[i]; vector<vector<int>>a(4); for(int i=0;i<4;++i){ a[i]=vector<int>(n[i]); for(int j=0;j<n[i];++j)cin>>a[i][j]; } for(int i=1,m;i<4;++i){ cin>>m; vector<vector<int>>g(n[i]); for(int j=0,u,v;j<m;++j){ cin>>u>>v;u--,v--;g[v].push_back(u); } multiset<int>cnt; for(int j=0;j<n[i-1];++j)cnt.insert(a[i-1][j]); for(int j=0;j<n[i];++j){ for(auto k:g[j]) cnt.erase(cnt.lower_bound(a[i-1][k])); if(cnt.empty())a[i][j]=INF; else a[i][j]+=*cnt.begin(); for(auto k:g[j]) cnt.insert(a[i-1][k]); } } int ans=*min_element(a[3].begin(),a[3].end()); if(ans>=INF)ans=-1; cout<<ans; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); //cin>>t; while(t--){ solve(); } return 0; }
G - 不让他们过去就可以了吗?
思路:求出最小的,若大于最小的都可以为winner
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void solve(){ int n;cin>>n; vector<int>ve(n); int mi=INF; for(int i=0;i<n;++i){ cin>>ve[i]; mi=min(mi,ve[i]); } int ans=0; for(int i=0;i<n;++i){ ans+=ve[i]>mi; } cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; while(T--){ solve(); } return 0; }
H - 唔...这个我真的能做到
思路:
有两种情况,1.x杯热水,x杯冷水,温度为(h+c)/2
2.x+1杯热水,x杯冷水,温度Tx=((x+1)h+xc)/(2x+1),且Tx'<0(求导),(h+c)/2<Tx<=h
若t<=(h+c)/2,答案即为2
否则可二分出答案,或解Tx=t,得出x=(t-h)/(h+c-2t),取x-1、x、x+1中最接近的即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int h,c,t;cin>>h>>c>>t; if(2*t<=c+h){ cout<<2<<'\n';return ; } auto check=[&](int x){ double fl=((double)(x+1)*h+x*c)/(2*x+1); int k=x+1; double fr=((double)(k+1)*h+k*c)/(2*k+1); double tt=t; return fabs(fl-tt)<=fabs(fr-tt); }; int l=0,r=1e9,x; while(l<=r){ int mid=l+r>>1; if(check(mid))x=mid,r=mid-1; else l=mid+1; } cout<<2*x+1<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); cin>>t; while(t--){ solve(); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int h,c,t;cin>>h>>c>>t; if(2*t<=c+h){ cout<<2<<'\n';return ; } int x=(t-h)/(h+c-2*t); double mi=LDBL_MAX; int ans; for(int i=max(0ll,x-1);i<=x+1;++i){ double v=fabs((double)((i+1)*h+i*c)/(double)(2*i+1)-(double)t); if(v<mi)mi=v,ans=2*i+1; } cout<<ans<<'\n'; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); cin>>t; while(t--){ solve(); } return 0; }
I - 你爱我不断提升的力量,对吧!
思路:要求分最大,那么一个人取最大,其他人取平均值即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void init(){ } void solve(){ int n,m,k;cin>>n>>m>>k; if(m==0)cout<<"0\n"; else{ int ma=min(n/k,m),mi=(m-ma+k-2)/(k-1);//cout<<ma<<' '<<mi<<'\n'; cout<<ma-mi<<'\n'; } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; init(); while(T--){ solve(); } return 0; }
J - 把德克萨斯放到我的小队来!
思路:n为偶数时,不需要跳;
n为奇数时,可以发现每隔n/2会跳跃一次,且从第二秒开始算,即跳(k-1)/(n/2)次,k加上多跳的对n取模即为当前位置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void init(){ } void solve(){ int n,k,ans;cin>>n>>k; if(n%2==0){ ans=k%n; if(ans==0)ans=n; cout<<ans<<'\n';return; } int l=(n+1)/2,s=n/2; if(k>=l){ int d=k-l+1,cnt=(d+s-1)/s; ans=(k+cnt)%n; } else ans=k%n; if(ans==0)ans=n; cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; init(); while(T--){ solve(); } return 0; }
K - 让德克萨斯来担任队长!
思路:数的范围为[-30,30],考虑枚举删去的数(区间中最大的数),将序列中大于该数的值修改为INT_MIN后求最大子串和即可,最后减去删去的数即为该情况的答案
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int ksm(int x,int y){ int res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res; } int c(int a,int b){ if(b>a)return 0; int res=1; for(int i=1,j=a;i<=b;++i,--j){ res=res*j%mod; res=res*ksm(i,mod-2)%mod; } return res; } int Lucas(int a,int b){ if(a<mod&&b<mod)return c(a,b); return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod; } void init(){ } void solve(){ int n;cin>>n; vector<int>ve(n); for(int i=0;i<n;++i)cin>>ve[i]; int ans=0; for(int i=0;i<=30;++i){ vector<int>a=ve; for(auto &j:a) if(j>i)j=INT_MIN; int s=0; for(int j=0,c=0;j<n;++j){ c+=a[j]; if(c<0)c=0; s=max(s,c); } ans=max(ans,s-i); } cout<<ans; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; init(); //cin>>t; while(t--){ solve(); } return 0; }
L - 小叶,掩护我们离开这里!
思路:一共有m=n*(n-1)/2条关系,要让每个人分数一样,即每个人赢k=m/n次,为(n-1)/2次;
当n为奇数时,每个人都赢k次刚好够m条关系,不需要平局;
当n为偶数时,可以发现多的关系为m%n,为n/2,刚好将每个人分数加一,即剩余的关系为平局
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void init(){ } void solve(){ int n;cin>>n; int k=(n-1)/2; vector<vector<int>>ve(n+1,vector<int>(n+1,0)); for(int i=1;i<=n;++i){ for(int j=i+1,u=1;u<=k;++u,++j){ int x=j%n; if(x==0)x=n; ve[i][x]=1; } } for(int i=1;i<n;++i){ for(int j=i+1;j<=n;++j){ if(ve[i][j])cout<<1<<' '; else if(ve[j][i])cout<<-1<<' '; else cout<<0<<' '; } } cout<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; init(); while(T--){ solve(); } return 0; }
M - 博士面罩下面是什么样的呢,悄悄看看吧..
思路:用双指针维护下前后缀相等的情况
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; void solve(){ int n;cin>>n; vector<int>ve(n+1),l(n+1),r(n+1); for(int i=1;i<=n;++i){ cin>>ve[i]; l[i]=l[i-1]+ve[i]; } r[n]=ve[n]; for(int i=n-1;i>=1;--i)r[i]=r[i+1]+ve[i]; int ans=0; int L=1,R=n; while(L<R){ while(r[R]<l[L]&&R>=1&&R>L)R--; if(!R||R<=L)break; if(l[L]==r[R])ans=max(ans,L+n-R+1); L++; } cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; while(T--){ solve(); } return 0; }