2020阿里實習生招聘筆試題

2021-10-04 15:21:17 字數 3108 閱讀 4514

小強有n個養雞場,第i個養雞場初始有a[i]只小雞,小強的每個養雞場每天早上都會增加k只小雞,到了下午小強會把雞最多的雞場賣掉一半雞,那麼小強想知道m天後他所有養雞場一共有幾隻雞。

第一行輸入三個正整數n,m,k;

第二行輸入n個正整數a[i]表示養雞場雞數量。

1<=n<=100000, 1<=m<=100000

1<=k<=10000, 1<=a[i]<=100000

輸出乙個整數表示答案。

樣例:輸入

3 3 100

100 200 400

輸出925

所有的雞場每天會增加k隻雞,我們不妨把雞場分成兩間屋子,一間屋子裝原來的雞a[i],一間屋子裝新增的雞k,每個養雞場新增的雞的數量都是一樣的,假如現在是第1天,第now號養雞場有最多雞,那麼需要賣掉(a[now]+k)/2隻雞,我們假設只賣第一間屋子的雞,那麼兩個屋子的雞數量變成了a[now]-(a[now]+k)/2和k,而其他雞場兩個屋子的雞數量是a[i]和k,比較大小的時候我們可以不需要比較第二間屋子的雞,因為所有雞場第二間屋子的雞數量都一樣,按照這個思路,每天只需要取第一間屋子雞最多的那個養雞場,然後a[now] = a[now]-(a[now] + x*k)/2,這裡x是指第x天,第二間屋子有x*k隻雞了,為了方便取第一間屋子最大的雞數量,我們把原雞場的雞數量放進乙個優先佇列當中,每天進行一次pop最大雞數量和push賣完剩下的雞數量。雞的總數為所有雞場第一間屋子+第二間屋子,這裡第二間屋子第m天總共有n*m*k隻雞,第一間屋子總共有的就是佇列裡面的值相加。

#include

#include

#include

#include

using

namespace std;

intmain()

for(

int i =

1; i <= m; i++

)long

long sum =0;

while

(!que.

empty()

) cout << sum + n*m*k << endl;

return0;

}

小強得到了乙個長度為n的序列,他想隨機選擇這個序列的乙個連續子串行,並求出這個序列的最大值,請你告訴他這個最大值的期望是多少?

輸入第一行n表示序列長度,1<=n<=10^6;

第二行為n個正整數,每個數字不超過10^5。

輸出這個最大值的期望,保留六位小數。

樣例:輸入

31 2 3

輸出2.333333

期望是指所有連續子串行的最大值相加除以連續子串行數量,乙個序列有多少連續子串行呢?假如序列長度為n,那麼長度為1的連續子串行有n個,長度為2的連續子串行有n-1個…所以一共有n*(n+1)/2個連續子串行,那我們把所有的連續子串行求出來然後把最大值相加?顯然很不合理,複雜度爆表,換乙個思路,如果以當前這個數字為最大值,哪些序列是滿足的?先往左找到左邊界再往右找到右邊界,例如4 1 2 3 2 1 4如果以3為最大值,滿足的範圍是1 2 3 2 1,滿足的子串行是1 2 3,1 2 3 2,1 2 3 2 1,2 3,2 3 2,2 3 2 1,3,3 2,3 2 1共九個,實際可以用兩個變數來計數,乙個記左邊有幾個數,乙個記右邊有幾個數,上面的例子左邊是1 2 3三個數,右邊是3 2 1三個數,一共有3*3=9種排列方式。這樣我們遍歷一遍就可以得到期望的分子,再除以數量即可。

#include

#include

#include

using

namespace std;

intmain()

long

long m = n*

(n+1)/

2;cout <<

1.0*sum/m << endl;

return0;

}

但是存在一些問題,比如 3 1 3,在計算第乙個3的時候會用到313序列,第二個也會用到,重複計算了,那麼我們把判斷大小的等於號只取左邊不取右邊,也就是

while

(i-l >=

0&& num[i-l]

<= num[i]

) l++

;while

(i+r < n && num[i+r]

< num[i]

) r++

;

這樣就避免了重複。

複雜度可能還是不足,但是筆試一小時的情況下也只能處理成這樣了。

最近正好學習了單調棧,對於求解這種左右邊界十分方便,所以重新修改了一下**,複雜度降低。

#include

#include

#include

#include

using

namespace std;

int n, l[

1000100

], r[

1000100];

long

long num[

1000100];

intmain()

l[i]

= sta.

top()+

1;sta.

push

(i);

}while

(!sta.

empty()

) sta.

pop();

sta.

push

(n);

for(

int i = n-

1; i >=

0; i--

)long

long sum =0;

for(

int i =

0; i < n; i++

) sum +

= num[i]

*(i - l[i]+1

)*(r[i]

-i+1);

double ans =

2.0*sum /n /

(n+1);

printf

("%.6f\n"

, ans)

;return0;

}

阿里 2020暑期實習生 筆試回憶

給若干點的座標,代表每乙個村子,現在要修一條平行於y軸且無限長的水渠,求所有村莊距離這條水渠垂直長度之和的最小值。include include include include include using namespace std intmain cout minval system pause ...

微軟實習生招聘筆試題目

微軟實習生招聘筆試題目 提交材料 1.不超過2頁的說明書,包括演算法,設計,使用說明,及程式編譯執行環境要求 2.c c 或c程式源 程式必須是可執行的 3.optional visual studio project 檔案,以及其他編譯必須檔案 4.請在截止時間11月30日 週日 前交卷 含週日當...

騰訊2012實習生招聘筆試題

由此觀之,基本上我知道的錯誤率就會很小。像基本的資料結構與演算法。但是不知道的錯誤率接近100 了,比如作業系統 資料庫 linux 設計模式的題。但是這些題其實也是很基礎的,與考研題類似,甚至還沒有達到考研題的難度。但是現在主要是攻破c 語言和資料結構與演算法的堡壘,其他型別的題目只能等後期 建設...