欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Codeforces Global Round 11——E随机+线性基待补

发布时间:2023/12/3 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Codeforces Global Round 11——E随机+线性基待补 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

A - Avoiding Zero

不难发现如果数组所有元素和为0一定不能满足条件,否则一定能满足。
假设所有元素和不为0尝试以下构造,如果正数和小于负数和的绝对值,那么逆序排列,否则顺序排列,这样一定满足题意。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=60; int a[N]; int main() {IO;int T=1;cin>>T;while(T--){int n;cin>>n;int s=0;int s1=0,s2=0;for(int i=1;i<=n;i++){cin>>a[i];if(a[i]<0) s1+=a[i];else s2+=a[i];s+=a[i];}if(s==0){cout<<"NO\n";continue;}sort(a+1,a+1+n);if(-s1<s2) reverse(a+1,a+1+n); cout<<"YES\n";for(int i=1;i<=n;i++) cout<<a[i]<<' ';cout<<'\n';}return 0;}

B - Chess Cheater

瞎搞的

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=100010; char s[N]; int n,k; int main() {IO;int T=1;cin>>T;while(T--){cin>>n>>k;cin>>s+1;priority_queue<int,vector<int>,greater<int>> q1,q2,q3;priority_queue<int> p1,p2;int cnt=0;for(int i=1;i<=n;i++){if(s[i]=='L') cnt++;else {if(!cnt) continue;if(i>cnt+1&&s[i-cnt-1]=='W'&&i<=n&&s[i]=='W') q1.push(cnt);else if(i>cnt+1&&s[i-cnt-1]=='W'||i<=n&&s[i]=='W') q2.push(cnt);else q3.push(cnt);cnt=0;}}if(cnt) {if(n>cnt&&s[n-cnt]=='W') q2.push(cnt);else q3.push(cnt);}int res=0;while(k&&q1.size()){auto v=q1.top();q1.pop();if(k>=v) res+=2*v+1,k-=v;else p1.push(v);}while(k&&q2.size()){auto v=q2.top();q2.pop();if(k>=v) res+=2*v,k-=v;else p2.push(v);}while(k&&(p1.size()||p2.size())){res+=2*k;k=0;}if(k&&q3.size()) {auto v=q3.top();res=2*min(k,v)-1;}for(int i=1;i<=n;i++){if(s[i]=='W'){if(i>1&&s[i-1]=='W') res+=2;else res++;}}cout<<res<<'\n';}return 0; }

C - The Hard Work of Paparazzi

刚开始以为是个图论题,但是有一个条件就是就算你先到了一个点你仍然要等到那个人出现的时间,也就是每个点的时间是确定的,因此每个点的时间是确定的考虑dp
状态表示:fif_ifi表示目前在第iii个点时答案的最大值
状态转移:fi=max(fi,fi+1)(∣xi−xj∣+∣yi−yj∣≤ti−tj)f_i=max(f_i,f_i+1)(|x_i-x_j|+|y_i-y_j|\leq t_i-t_j)fi=max(fi,fi+1)(xixj+yiyjtitj)

这样转移会发现复杂度爆炸O(n2)O(n^2)O(n2),我们可以发现还有个东西一直没有用也就是地图的尺寸rrr,由于tit_iti是顺序给出的如果当前的ti−tj≥2rt_i-t_j\ge 2rtitj2r不难发现1−j1-j1jf1−jf_{1-j}f1j都能更新fif_ifi由此尝试维护前缀进行优化。
时间复杂度好像是O(nr)O(nr)O(nr)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=100010; int r,n; int f[N]; struct node {int x,y,t; }a[N]; int mx[N]; int main() {IO;int T=1;//cin>>T;while(T--){cin>>r>>n;for(int i=1;i<=n;i++) cin>>a[i].t>>a[i].x>>a[i].y;memset(f,-0x3f,sizeof f);memset(mx,-0x3f,sizeof mx);a[0]={1,1,0};f[0]=mx[0]=0;for(int i=1;i<=n;i++){for(int j=i-1;j>=0;j--){if(a[i].t-a[j].t>=2*r) {f[i]=max(f[i],mx[j]+1);break;}if(abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y)<=a[i].t-a[j].t) f[i]=max(f[i],f[j]+1);}mx[i]=max(mx[i-1],f[i]);}int res=0;for(int i=1;i<=n;i++) res=max(res,f[i]);cout<<res<<'\n';}return 0; }

剩下的题待补

D - Unshuffling a Deck

今天早上起来想了一下这个题,想了个贪心的做法然后上课前交代码发现贪心思路不行,然后吃完午饭又想了个做法水过去了

尝试每次使得一个数排列归位。这里尝试按照n−1n−2…1n-1\ n-2\dots \ 1%n1 n2 1的顺序
首先我们让排好序的排成(目前已经有cnt个数“归位”)这样子{[n,n−1,n−2,...,n−cnt+1][...n−cnt][....]}\{[n,n-1,n-2,...,n-cnt+1][...n-cnt][....]\}{[n,n1,n2,...,ncnt+1][...ncnt][....]}我们只需要这样划分就可以在此归位一个数
{[1]...[1][1]⏟cnt[len1][len2]}\{ \underbrace{[1]...[1][1]}_{cnt}[len_1][len_2]\}{cnt[1]...[1][1][len1][len2]}
这样操作后原序列即变成{[......][n−cnt,n−cnt+1,...,n]}\{[......][n-cnt,n-cnt+1,...,n]\}{[......][ncnt,ncnt+1,...,n]}
然后如法炮制的操作,一共进行n次即可归位。还有些细节可以看代码

细节1:n奇偶性,最后一次操不能让序列变成全部逆序的情况,需要顺序
细节2:划分需要至少划分2个断,最后需要把划分成1个段(无效操作)清除掉。

上述方法一定能在n次操作以内完成序列顺序。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=60; int n,cnt; int a[N],b[N]; vector<int> ans[N]; int main() {IO;int T=1;//cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];bool flag;int now=n;if(n&1) flag=0;else flag=1;for(int k=1;k<=n;k++){int p;for(int i=1;i<=n;i++) if(a[i]==now) p=i;//cout<<p<<':';//cout<<(int)flag<<'\n';if(!flag)// 左边整齐{for(int i=1;i<=cnt;i++) ans[k].push_back(1);if(p-cnt) ans[k].push_back(p-cnt);if(n-p) ans[k].push_back(n-p);for(int i=p+1,j=1;i<=n;i++,j++) b[j]=a[i];// p+1~n -> 1~n-p n-pfor(int i=cnt+1,j=n-p+1;i<=p;i++,j++) b[j]=a[i];// cnt+1~p -> n-p+1 p-cntfor(int i=1,j=n;i<=cnt;i++,j--) b[j]=a[i];// 1~cnt -> n~n-cnt+1 cntfor(int i=1;i<=n;i++) a[i]=b[i];}else{if(p-1>0) ans[k].push_back(p-1);if(n-cnt-p+1>0) ans[k].push_back(n-cnt-p+1);for(int i=1;i<=cnt;i++) ans[k].push_back(1);for(int i=1,j=n-p+2;i<=p-1;i++,j++) b[j]=a[i];for(int i=p,j=cnt+1;i<=n-cnt;i++,j++) b[j]=a[i];for(int i=n-cnt+1,j=cnt;i<=n;i++,j--) b[j]=a[i];for(int i=1;i<=n;i++) a[i]=b[i];}now--;cnt++;flag^=1;}int res=0;for(int i=1;i<=n;i++)if(ans[i].size()>1) res++;cout<<res<<'\n';for(int i=1;i<=n;i++){if(ans[i].size()>1){cout<<ans[i].size()<<' ';for(auto t:ans[i]) cout<<t<<' ';cout<<'\n';}}}return 0; }

E - Xum

要加哟哦~

总结

以上是生活随笔为你收集整理的Codeforces Global Round 11——E随机+线性基待补的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。