hdu4908 中位数子串
生活随笔
收集整理的這篇文章主要介紹了
hdu4908 中位数子串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你N個數字組成的數列,然后問你這里面有多少個是以M為中位數的子序列。
? ? ? ?(1) 就是只有他自己的那種情況 那么sum+1
? ? ? ?(2) 從自己開始向左延伸,x, x - 1, x - 2 ...這種可以記錄大于m的個數max和小于m的個數min當兩個數相等的時候(min == max)就 sum++,然后在這樣 mark[max - min]++;記錄差值產生的次數,可以開兩個數組,一個寸正差,一個存負差,或者直接開一個容器,我開的是容器,這個地方隨意
? ? ? 給你N個數字組成的數列,然后問你這里面有多少個是以M為中位數的子序列。
思路:
? ? ? 首先分四中簡單的情況求? ? ? ?(1) 就是只有他自己的那種情況 那么sum+1
? ? ? ?(2) 從自己開始向左延伸,x, x - 1, x - 2 ...這種可以記錄大于m的個數max和小于m的個數min當兩個數相等的時候(min == max)就 sum++,然后在這樣 mark[max - min]++;記錄差值產生的次數,可以開兩個數組,一個寸正差,一個存負差,或者直接開一個容器,我開的是容器,這個地方隨意
? ? ? ?(3) 從自己開始向又延伸,跟上面的操作一樣,唯獨就是在mark[max - min]++那不一樣,這一步不用記錄差值的出現次數,而是直接算 sum += mark[min-max],這里很簡單,就是優化了暴力,這個題目如果直接暴力是O(n^2)的,這樣算出來是O(N)的。不是很難理解就不多解釋了,還不懂得看看下面的代碼就懂了,水題一道。
#include<stdio.h> #include<map>#define N 44000 using namespace std;map<int ,int>mark;int num[N] ,L[N] ,R[N];int main () {int sum ,n ,m ,i ,mk;while(~scanf("%d %d" ,&n ,&m)){for(i = 1 ;i <= n ;i ++){scanf("%d" ,&num[i]);if(num[i] == m) mk = i;}mark.clear();sum = 0; int min = 0,max = 0;for(i = mk + 1 ;i <= n ;i ++){num[i] < m ? min++ : max++;if(min == max) sum ++;mark[max - min] ++;}min = 0 ,max = 0;for(i = mk - 1 ;i >= 1 ;i --){num[i] < m ? min ++ : max ++;if(min == max) sum ++;sum += mark[min - max];}printf("%d\n" ,sum + 1);}return 0; }
總結
以上是生活随笔為你收集整理的hdu4908 中位数子串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu4909 状态压缩(偶数字符子串)
- 下一篇: hdu4907 水dp 或者set