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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

csp真题 202109-2非零段划分C++代码(100分)

發布時間:2023/12/10 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 csp真题 202109-2非零段划分C++代码(100分) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

試題編號: 202109-2
試題名稱: 非零段劃分
時間限制: 1.0s
內存限制: 512.0MB

樣例1輸入

11 3 1 2 0 0 2 0 4 5 0 2

樣例1輸出

5

樣例1解釋
p=2時,A=[3,0,2,0,0,2,0,4,5,0,2],5個非零段依次為[3]、[2]、[2]、[4、5]和[2];此時非零段個數達到最大。

樣例2輸入

14 5 1 20 10 10 10 10 15 10 20 1 5 10 15

樣例2輸出

4

樣例2解釋
p=12時,A=[0,0,20,0,0,0,0,15,0,20,0,0,0,15],4個非零段依次為[20]、[15]、[20]和[15];此時非零段個數達到最大。

樣例3輸入

3 1 0 0

樣例3輸出

1

樣例3解釋
p=1時,A=[1,0,0],此時僅有1個非零段[1],非零段個數達到最大。

樣例4輸入

3 0 0 0

樣例4輸出

0

樣例4解釋
無論p取何值,A都不含有非零段,故非零段個數至多為0。

70分代碼及思路:
思路:
1.將所有數據存儲到一個數組A中,并記錄最大值max_A;
2.p從1開始遍歷到最大值max_A,記錄每一次p值下的非零段的個數最大值到數組max1中。
3.判斷非零段個數:遍歷數組,找到每一個不為0的值,如果該數前一個數為0或者該數是數組的第一個數,非零段個數加1。
4.遍歷數組max1,輸出最大值。
分析:
該方法屬于常規思路,比較簡單,無任何算法優化,有很多循環遍歷,且有雙層循環,由題目給出的數據范圍,在雙層循環中,循環次數有可能達到10^9,顯然會超時。

#include <iostream> using namespace std;int main() {int n;int i=0,p=0,max_A=0,max=0;cin>>n;int A[n]={0};for(i=0;i<n;i++){cin>>A[i];if(A[i]>max_A) //記錄數組A中的最大值 {max_A=A[i];}}int max1[max_A]={0}; //開辟數組用來存儲每一個p值下的非零段的最大值 for(p=1;p<max_A;p++) //p從1開始遍歷 {for(i=0;i<n;i++) //將數組中小于p的數置為0 {if(A[i]<p){A[i]=0;}}for(i=0;i<n;i++) //遍歷數組 {if(A[i]!=0){//若不為0,判斷是否是數組的第一個數或者該數的前一個數為0,如果是,非零段加1 if(i==0||A[i-1]==0){max=max+1;}}}max1[p]=max;max=0;}for(i=1;i<max_A;i++) if(max1[i]>max){max=max1[i];}cout<<max;return 0; }

提交結果如下:

如果要拿到滿分,那么用常規的思路邏輯肯定不行,必須要做一定的優化處理,在參考b站視頻教程后整理如下:
1.讀入數組時插入set,對數組進行去重和排序,(方便p值的選取)。
2.利用向量vector,將set集合中每個元素出現的位置存儲在同一個vector向量中。
3.統計初始的非零段個數作為參考值。
(與前一種方法有點區別,在數組開頭和最后加0,只需判斷當前數不為0并且前一位數為0,非零段個數加1即可)
4.p依次從set中取值(從小到大)(如果值為0,跳過),依據位置向量獲得每個值在數組A中的位置。
將對應位置的值賦值為0
如果該位置的前后的值都大于0,則非零段數加1;
如果該位置的前后的值都等于0,則非零段數減1;
其他情況下非零段個數不變。

更新非零段的最大值。
該方法的優點在于:
通過向量對應的位置坐標,判斷坐標位置前后元素的值進行判斷即可,不必在每一個p值下都對數組進行循環遍歷,降低了時間復雜度。
此方法思路來源b站,可參考b站視頻內容

滿分代碼:

#include <bits/stdc++.h> using namespace std;int A[500002]= {0}; vector<int> Vector[10001]; set<int> Set;int main() {int n;cin>>n;for(int i=1; i<=n; i++) {cin>>A[i];Set.insert(A[i]);Vector[A[i]].push_back(i);}int number=0; //非零段個數for(int i=1; i<=n; i++) { //找出當前非零段的個數if((A[i]>0)&&(A[i-1]==0))number++;}int temp;int number_max; //非零段個數的最大值temp=number_max=number;set<int>::iterator p=Set.begin();//用迭代器來訪問set集合//p的值從集合開始遍歷if(*p==0) //如果集合中的元素為0,則直接從下一個元素開始p++;for(p; p!=Set.end(); p++) {vector<int> &Vector1=Vector[*p]; //引用Vector[*p]為Vector1 for(int i=0; i<Vector1.size(); i++) { //集合中該元素出現的總次數int k=Vector1[i]; A[k]=0;if((A[k-1]!=0)&&(A[k+1]!=0))temp++;if((A[k-1]==0)&&(A[k+1]==0))temp--;}number_max=max(number_max,temp);}cout<<number_max<<endl;return 0;}

提交結果如下:

總結

以上是生活随笔為你收集整理的csp真题 202109-2非零段划分C++代码(100分)的全部內容,希望文章能夠幫你解決所遇到的問題。

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