23 暑假友谊赛 No.4
23 暑假友谊赛 No.4
思路:用差分数组标记每个周期的夜晚,(从0开始)
#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; const int m=1825*100; void solve(){ int n;cin>>n; vector<int>cnt(m+110,0); for(int i=1,l,r,h;i<=n;++i){ cin>>h>>l>>r; if(l<=r){ int s=0,t=h-1; while(s<=m){ cnt[s]++,cnt[l+1]--; cnt[r]++,cnt[t+1]--; s+=h,t+=h,l+=h,r+=h; } }else{ while(r<=m){ cnt[r]++,cnt[l+1]--; r+=h,l+=h; } } } for(int i=1;i<m;++i)cnt[i]+=cnt[i-1]; for(int i=0;i<m;++i){ if(cnt[i]==n){ cout<<i;return ; } } cout<<"impossible"; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }
思路:枚举每条边,以该边为平行杯壁的边,将所有的点以该边为界线分为两部分,分别找到两部分中最远的点,两点与边的距离和即为当前情况的最小杯直径,取所有情况的直径的最小值
#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=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750; const int inf=0x3f3f3f3f3f3f; const double eps=1e-6; struct E{ int x,y; E(){} E(int _x,int _y){x=_x,y=_y;} E operator-(E b){return E(x-b.x,y-b.y);} double len(){return ::hypot(x,y);} }; void solve(){ int n; cin>>n; double ans=INF; vector<E>ve(n); for(int i=0;i<n;++i)cin>>ve[i].x>>ve[i].y; auto cross=[](E a,E b){ return (double)(a.x*b.y-a.y*b.x); }; auto dis=[&](E p,E a,E b){ return cross(p-a,b-a)/(b-a).len(); }; for(int i=0;i<n;++i) for(int j=0;j<i;++j){ double l=INF,r=-INF; for(int k=0;k<n;++k){ l=min(l,dis(ve[k],ve[i],ve[j])); r=max(r,dis(ve[k],ve[i],ve[j])); } r-=l; ans=min(ans,r); } cout<<fixed<<setprecision(10)<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //cin>>T; while(T--){ solve(); } return 0; }
思路:每次打red后打的球可再返回桌子,求出red的个数s,非red的最大分值ma,除red外的所有分值le,那么答案为s(1+ma)+le
#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; const int m=1825*100; void solve(){ map<string,int>mp; mp["red"]=1,mp["yellow"]=2,mp["green"]=3,mp["brown"]=4,mp["blue"]=5,mp["pink"]=6,mp["black"]=7; int n,ma=0,cnt=0,le=0;cin>>n; string s; for(int i=0;i<n;++i){ cin>>s; ma=max(ma,mp[s]); if(s=="red")cnt++; else le+=mp[s]; } if(le)cout<<cnt*(1+ma)+le; else cout<<1; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }
思路:给了t,s为t排序后的串,问s转为t的操作,维护s和t的前i个字符都相同,若不相同则往后找到与之交换的字符即可
#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; const int m=1825*100; void solve(){ string t;cin>>t; string s=t; sort(s.begin(),s.end()); for(int i=0;i<s.size();++i){ if(s[i]!=t[i]){ for(int j=i+1;j<s.size();++j){ if(s[j]==t[i]){ if(s[i]>=s[j])cout<<i+1<<' '<<j+1<<'\n'; else cout<<j+1<<' '<<i+1<<'\n'; swap(s[i],s[j]); break; } } } } return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }
思路:将房子按价格少、容量小排序,将部门容量按大到小排序,暴力枚举即可
#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; void solve(){ int n,m;cin>>n>>m; vector<PII>ve(n); vector<pair<PII,int>>g(m); for(int i=0;i<n;++i)cin>>ve[i].first,ve[i].second=i+1; for(int i=0;i<m;++i)cin>>g[i].first.second; for(int i=0;i<m;++i)cin>>g[i].first.first,g[i].second=i+1; sort(ve.begin(),ve.end(),greater<PII>()); sort(g.begin(),g.end()); vector<int>st(m+1,0),ans(n+1); for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ if(!st[g[j].second]&&g[j].first.second>=ve[i].first){ ans[ve[i].second]=g[j].second;st[g[j].second]=1; break; } if(j==m-1){cout<<"impossible";return ;} } } for(int i=1;i<=n;++i)cout<<ans[i]<<' '; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }
思路:求k次操作后有正面硬币的期望值,f[i][j]表示扔第i次有j枚硬币的期望值,i从0开始,即:f[i+1][j]+=f[i][j]*0.5,f[i+1][j+1]+=f[i][j]*0.5(分别为扔反面、正面)
当已有n枚正面时,f[i+1][j]+=f[i][j]*0.5,f[i+1][j-1]+=f[i][j]*0.5(分别为扔正面、反面)
#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; void solve(){ int n,k;cin>>n>>k; vector<vector<double>>f(k+1,vector<double>(n+1,0)); f[0][0]=1; for(int i=0;i<k;++i) for(int j=0;j<=min(n,i);++j){ f[i+1][j]+=f[i][j]*0.5; if(j==n)f[i+1][j-1]+=f[i][j]*0.5; else f[i+1][j+1]+=f[i][j]*0.5; } double ans=0; for(int i=1;i<=n;++i)ans+=f[k][i]*i; cout<<fixed<<setprecision(10)<<ans; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }
思路:靠近终点依次走x,y,z方向,若走了一步后发现与另一个机器重合,返回后走另一个方向即可
#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; struct E{ int x,y,z; }s1,s2,t1,t2; bool eq(E a,E b){ return a.x==b.x&&a.y==b.y&&a.z==b.z; } void pr(E s,E t){ cout<<"("<<s.x<<' '<<s.y<<' '<<s.z<<") "; cout<<"("<<t.x<<' '<<t.y<<' '<<t.z<<")\n"; } void solve(){ cin>>s1.x>>s1.y>>s1.z>>t1.x>>t1.y>>t1.z; cin>>s2.x>>s2.y>>s2.z>>t2.x>>t2.y>>t2.z; pr(s1,s2); while(1){ if(s1.x==t1.x&&s1.y==t1.y&&s1.z==t1.z&&s2.x==t2.x&&s2.y==t2.y&&s2.z==t2.z)break; E v=s1,p;p={0,0,0}; if(v.x!=t1.x){ if(t1.x>v.x)v.x++;else v.x--; if(eq(v,s2))p={0,-1,0}; }else if(v.y!=t1.y){ if(t1.y>v.y)v.y++;else v.y--; if(eq(v,s2))p={0,0,-1}; }else if(v.z!=t1.z){ if(t1.z>v.z)v.z++;else v.z--; if(eq(v,s2))p={-1,0,0}; } if(!eq(p,{0,0,0}))v=s1,v.x+=p.x,v.y+=p.y,v.z+=p.z; s1=v; v=s2,p={0,0,0}; if(v.x!=t2.x){ if(t2.x>v.x)v.x++;else v.x--; if(eq(v,s1))p={0,-1,0}; }else if(v.y!=t2.y){ if(t2.y>v.y)v.y++;else v.y--; if(eq(v,s1))p={0,0,-1}; }else if(v.z!=t2.z){ if(t2.z>v.z)v.z++;else v.z--; if(eq(v,s1))p={-1,0,0}; } if(!eq(p,{0,0,0}))v=s2,v.x+=p.x,v.y+=p.y,v.z+=p.z; s2=v; pr(s1,s2); } return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //cin>>t; while(T--){ solve(); } return 0; }
思路:找到取模后最小的数
void solve() { int n; cin >> n; vector<int> ve(n); for (int i = 0; i < n; ++i) { cin >> ve[i]; } int x; cin >> x; int ans = inf, res; for (int i = 0; i < n; ++i) { if( x % ve[i] <ans) ans = x%ve[i], res = ve[i]; } cout << res << '\n'; }
思路:算总分
void solve() { int n; cin >> n; map<int, double> mp; mp[0] = 2.0, mp[1] = 1.0, mp[2] = 0.5, mp[4] = 0.25, mp[8] = 0.125, mp[16] = 0.0625; double ans = 0; for (int i = 0; i < n; ++i) { int x; cin >> x; ans += mp[x]; } printf("%.8f", ans); }
思路:将每个点按向量划分,按与电视的距离排序,求最长上升子序列的个数即可
#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; void solve(){ PII T,v,u; cin>>T.first>>T.second; int n;cin>>n; map<PII,vector<PII>>mp; for(int i=1,h,d;i<=n;++i){ cin>>v.first>>v.second>>h; v.first-=T.first,v.second-=T.second; d=abs(__gcd(v.first,v.second)); u.first=v.first/d,u.second=v.second/d; mp[u].push_back({abs(v.first)+abs(v.second),h}); } int ans=0; for(auto [a,b]:mp){ sort(b.begin(),b.end()); vector<int>q; q.push_back(b.begin()->second); for(int i=1;i<b.size();++i){ if(b[i].second>q.back())q.push_back(b[i].second); else *lower_bound(q.begin(),q.end(),b[i].second)=b[i].second; } ans+=q.size(); } cout<<ans; return; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //cin>>t; while(t--){ solve(); } return 0; }