日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

codeforce训练2总结

發布時間:2025/4/5 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 codeforce训练2总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目列表

A.most unstable array
題號
題意
n個非負正數和為m,求所有相鄰兩數絕對值之和,即
分析
選擇其中一個數為m本身,其他都取0。
為便于分析,分為兩種情況來看。
如果n為奇數,取法有很多種。
只需要排列的開頭和結尾都是0,并且非零數以0為間隔,這樣的差的絕對值最大。每個非零數aia_iai?與其兩邊的零相差絕對值為2*aia_iai?,然后進行累加,結果就是2m。舉例,5個數和為7,則可以取[0,3,0,4,0],相鄰兩數差的絕對值之和為3+3+4+4=14=27=2m;或者取[0,1,0,6,0],相鄰兩數差的絕對值之和為1+1+6+6=14=27=2m,或者取[0,7,0,0,0]=7+7=14=2m
當然這是奇數的情況。
如果n為偶數,只能[0,m,0,0,…]這樣來做。

綜上,最簡單的做法如下:
n= =1時,排列為[m]結果為0
n==2時,排列為[m,0]結果為m
n>=3時,排列為[0,m,0,0,0](其中n-1個0),結果為2m

ac代碼

#include<iostream>using namespace std;int t; long long n,m; int main(){cin>>t;while(t--){cin>>n>>m;if(n==1){cout<<0<<endl;continue; } if(n==2){cout<<m<<endl;continue;}cout<<m*2<<endl;} }

B.Two Arrays And Swaps
題號280477B - 12
題意
給定兩個等長的序列a和b,允許兩個序列交換數字,但是給定交換次數的最大值k。要求在不超過k次交換使得a序列元素之和變得最大

分析
a從小到大排序,b從大到小排序,b中最大的與a中最小的交換。
當然需要分情況討論
【1】交換次數==0,直接輸出sum
【2】a所有數字都比b中的大,不需要交換,直接輸出sum
【3】a中所有數字都比b中的小,那么交換k次。
【4】b中部分數字比a中部分數字大,兩個指針來比較

int p1=0,p2=0;//p1是a中的指針,p2是b中的指針while(p1!=n&&p2!=n&&k!=0){//a和b沒遍歷完,交換次數沒用完if(b[p2]>a[p1]){//b中的元素大于a中的元素,交換sum+=b[p2]-a[p1];k--;//交換次數用掉一次p2++;//此數已交換,b的指針后移}p1++; //a的指針后移}

ac代碼
ac代碼鏈接代碼和原題

#include<iostream> #include<algorithm> using namespace std; const int maxn=40; int t,n,k,a[maxn],b[maxn]; int main(){cin>>t;while(t--){cin>>n>>k;long long sum=0;for(int i=0;i<n;i++){cin>>a[i];sum+=a[i];//求和 } for(int i=0;i<n;i++){cin>>b[i]; } if(k==0){//沒有交換 cout<<sum<<endl;continue;}sort(a,a+n);//從小到大 sort(b,b+n,greater<int>());//從大到小 if(b[0]<=a[0]){//b全都小 cout<<sum<<endl;continue;}else if(b[n-1]>=a[n-1]){//b全都大for(int i=0;i<k;i++){sum+=b[i]-a[i];} } else{//有大有小 int p1=0,p2=0;while(p1!=n&&p2!=n&&k!=0){if(b[p2]>a[p1]){sum+=b[p2]-a[p1];k--;p2++;}p1++; }}cout<<sum<<endl;sum=0;}return 0; }

D.
需要采用優先隊列,每次按照區間長度排序,區間長度相同則做左端點小的優先級高。

bfs+二分賦值即可
bfs模板中的隊列改為優先隊列priority_queue,每次取出長度最大的連續為0的區間,然后取中點賦值,如果長度相等,則取區間左端點靠前的區間來取中點賦值。

#include<iostream> #include<queue>//priority_queue #include<cstring> using namespace std; const int maxn=2e5+10;int t,n,a[maxn];struct seg{int l;int r;int len;bool operator<(const seg&s2)const{if(s2.len==len)//長度相同,左端點小者優先 return l>s2.l;elsereturn len<s2.len;//長度大者優先 } };seg start,tmp,tmp2;int main(){cin>>t;while(t--){priority_queue<seg> pq;memset(a,0,sizeof(a));cin>>n;//bfsstart.l=1;//起點start.r=n;start.len=n;pq.push(start);//起點入隊int cnt=0;while(!pq.empty()){tmp=pq.top();//取點pq.pop();//出隊,防止死循環cnt++;//待賦值的數int mid=(tmp.l+tmp.r)/2;//取中點if(a[mid]==0){a[mid]=cnt;}//二分放進來if(tmp.l<=mid-1){tmp2.l=tmp.l;tmp2.r=mid-1;tmp2.len=tmp2.r-tmp2.l+1;pq.push(tmp2); }if(mid+1<=tmp.r){tmp2.l=mid+1;tmp2.r=tmp.r;tmp2.len=tmp2.r-tmp2.l+1;pq.push(tmp2);}}for(int i=1;i<=n;i++){cout<<a[i]<<" ";}cout<<endl;}}

總結

以上是生活随笔為你收集整理的codeforce训练2总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。