A
在只能横着切披萨和竖着切的时候,必须保证均匀的切割才能保证所有披萨面积一致,若横着切不均匀,那么在考虑某一列的披萨,则它们的宽不一致,则不能满足题意。
依照此想法枚举横着切的次数即可。复杂度O(k)
#include<bits/stdc++.h> using namespace std; #define int long long int n,k; double noww,squ; signed main() { cin>>n>>k; noww=n; for(int i=0;i<=k;++i) { double x1=n*1.0/(i+1); double x2=n*1.0/(k-i+1); if(abs(x1-x2)<=noww) {squ=x1*x2; noww=abs(x1-x2); } } printf("%.2lf",squ); }B
模拟,但不能在区间内每个应当插入相同字母逐次模拟,这样复杂度为O(n*n),超时,利用q小的特点,应当对区间后所有字母统一向后移动两倍区间长,后修改字母,这样复杂度只有O(q*n)。
#include<bits/stdc++.h> using namespace std; #define maxx 322000 int n,neww,q,a,b; char s[maxx]; char p[maxx]; void insertt(int i,int sz) { for(int j=n;j>=i+sz;--j) s[j+sz]=s[j]; for(int j=i;j<i+2*sz;++j) s[j]=p[j-i+1]; n=n+sz; } signed main() { cin>>n>>q; for(int i=1;i<=n;++i) cin>>s[i]; for(int i=1;i<=q;++i) { cin>>a>>b; neww=0; for(int i=a;i<=b;++i) {p[++neww]=s[i]; p[++neww]=s[i]; } insertt(a,b-a+1); } for(int i=1;i<=n;++i) cout<<s[i]; }C
贪心,将数字排序后,由于最大最小值才影响答案,我们优先将最大最小值进行合并后求出平均值,枚举最大最小值个数,注意同时计算和,或处理前缀和,避免平方复杂度。复杂度O(n)
#include<bits/stdc++.h> using namespace std; #define int long long #define maxx 322000 int n,k,q,a,b; int all[maxx]; double pj,ans; int nl,nr; signed main() { cin>>n>>k; for(int i=1;i<=n;++i) cin>>all[i]; sort(all+1,all+1+n); for(int i=n;i>n-k;--i) nr=nr+all[i]; if(k==n) { cout<<0; return 0; } ans=max(nr*1.0/k,all[n-k]*1.0)-min(nr*1.0/k,all[1]*1.0); for(int i=1;i<=k;++i) { nr=nr-all[n-k+i]; nl=nl+all[i]; double q=(nr+nl)*1.0/k; ans=min(ans,max(q,all[n-k+i]*1.0)-min(q,all[i+1]*1.0)); } printf("%lf",ans); }D
二分,答案具有单调性,随着n的增加,1-n的最短路逐渐减少,当n过大时无法到达。
二分车重,随后给定车重下进行最短路,复杂度O(nlognlogw),最短路可以使用堆优化的迪杰斯特拉算法实现。
#include<bits/stdc++.h> using namespace std; #define int long long #define maxx 222210 #define INF 0x3f3f3f3f int l,r; int n,m,h,a,b,c,t; struct mre //[i,j] { int st,ed,val,lim; }; struct mre E[maxx]; map<int,vector<int>> M; vector<int> G[maxx]; int d[maxx]; void dij(int q) { M[0].push_back(1); for(int i=1;i<=n;++i) d[i]=INF; while(!M.empty()) { int a=M.begin()->first; int b=M.begin()->second[M.begin()->second.size()-1]; M.begin()->second.pop_back(); if(M.begin()->second.size()==0) M.erase(M.begin()); if(d[b]!=INF) continue; d[b]=a; for(int i=0;i<G[b].size();++i) {if(E[G[b][i]].lim<q) continue; M[a+E[G[b][i]].val].push_back(E[G[b][i]].ed);} } } int check(int mid) { dij(mid); if(d[n]<=h) return 1; else return 0; } signed main() { cin>>n>>m>>h; for(int i=1;i<=m;++i) {cin>>a>>b>>c>>t; E[++neww].st=a; E[neww].ed=b; E[neww].lim=c; E[neww].val=t; G[a].push_back(neww); E[++neww].st=b; E[neww].ed=a; E[neww].lim=c; E[neww].val=t; G[b].push_back(neww); r=max(c,r); } l=0; //check(6); dij(0); if(d[n]==INF) { cout<<-1; return 0; } r=r+1; while(l<r) { int mid=(l+r)/2; if(check(mid)) l=mid+1; else r=mid; } cout<<l-1; }