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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CodeForces - 1198A MP3(尺取)

發布時間:2024/4/11 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1198A MP3(尺取) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出n個數字,表示不同的數據,現在我們需要對數據進行壓縮,壓縮的規則是:

現在給出一個I,表示內存大小為,n個數字中,相同的數據可以占用同一片內存,不同的數據必須占用不同的內存

在以上前提下,我們需要確定一個范圍[l,r],這個區間不是數組的下標,而是數字的范圍,然后對n個數進行操作:

  • 在這個范圍內的數字不用改變
  • 小于l的所有數字都改成l
  • 大于r的所有數字都改成r
  • 現在我們需要求出在滿足上述所有條件的情況下,n-(r-l+1)的最小值

    題目分析:這個題就在讀題上廢了好大的功夫,簡單來說為了讓n-(r-l+1)盡量小,那么就要讓r-l+1盡量大,也就是讓整個區間盡量長,因為[l,r]他不是數組的下標,但我們可以將其轉換為數組的下標來處理,其實就是對原數組排個序就好了,然后[l,r]就可以當下標來用了,首先我們必須知道,若想讓r-l+1盡可能的大,那么就必須讓區間[l,r]之間不同數字的個數恰好等于K才行,這算一種貪心的策略吧,顯而易見?在處理之前,我們先求出來K來表示上面內存大小公式的計算結果,若K大于等于n個數中不同數字的個數,那么直接輸出0即可,根本不用壓縮了,而且注意一下當I求出來的指數很大的時候,大概大于20的時候,我們就可以直接輸出0了,因為2的20次方已經大于1e6了,比n都大了,肯定滿足條件

    在判斷完上述情況之后,剩下的我們可以用尺取法跑一邊整個數組,這個尺取需要仔細設計一下,因為他是普通求和尺取的一種小變形,我們先用一個數組維護一下前綴和,但這個前綴和維護的是0~i中不同數字的個數,然后跑尺取的時候讓r一直遞增,讓l隨著r根據K來移動就行了,總的時間復雜度是n+n,也就是O(n),常數是2,具體實現看代碼吧

    代碼:

    #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4e5+100;int a[N],b[N];int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n,I;scanf("%d%d",&n,&I);for(int i=1;i<=n;i++)scanf("%d",a+i);I=I*8/n;int k=I>20?(1<<20):(1<<I);sort(a+1,a+1+n);a[0]=-1;//因為a[i]的取值范圍會涉及到0,所以我們初始化一個一定與a[i]不相等的數 for(int i=1;i<=n;i++){if(a[i]==a[i-1])b[i]=b[i-1];elseb[i]=b[i-1]+1;}if(k>=b[n])//特判一下return 0*printf("0");int ans;int l=1,r=1;int mmin=inf;while(r<=n)//尺取{ans=b[r++]-b[l]+1;//先求出當前范圍內有多少個不同的數if(ans>k)//如果這個值大于內存K的話,就讓l逼近r{ans-=b[l++];while(ans>k)//持續逼近{ans+=b[l++];//注意要將之前的值加回來ans-=b[l];//然后再減去當前位置的值}}if(ans==k)//如果滿足條件,更新答案mmin=min(mmin,n-(r-l));}printf("%d\n",mmin);return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的CodeForces - 1198A MP3(尺取)的全部內容,希望文章能夠幫你解決所遇到的問題。

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