水杯 (資料結構作業)

2021-09-01 05:23:33 字數 1940 閱讀 8311

演算法與資料結構實驗題12.2水杯

有 n 個水杯如圖所示放置

從上到下,編號由 1 開始一直到 n,容量 ai 也依次增大(ai+1 > ai),如果

i 號杯子存的水超過了它的容量,則會像 i+1 號水杯流,以此類推現在給你兩個操作

操作一: 1 x y 給 x 號杯子加 y 容量的水操作二: 2 x 查詢 x 杯子裡有多少水。

輸入第一行為乙個正整數 n

接下來 n 個元素,表示第 i 個水杯的容量接著輸入操作的個數 q

接下來 q 行操作。

60%的資料 1<=n<=100,1<=ai,y<=100.

100%的資料 1<=n<=100000,1<=ai,y<=1000000000.

對於每個操作二,輸出對應的值。

輸入示例

輸出示例4

5 1058

1 1 4

2 11 2 5

1 1 4

2 12 2

乍一看,暴力遍歷,能過九個點。

仔細一想,我們多遍歷了許多已經裝滿水的水杯,把這些水杯拿走就行了(拿不拿走對結果沒影響,已經滿了的水杯,澆了水,也會往下流。不如直接把它拿走)

這是是個並查集,分為兩個集合,澆滿水的集合和未澆滿的集合。我們統計未澆滿的集合就行了,澆滿的做個標記就行了。不停地按順序把澆滿的位置退出未澆滿的集合。

#include #include using namespace std;

int cup[100100]=; // 容量集合

int a[100100]; //記錄每個水杯當前的水的體積

int main()

scanf ("%d",&q);

set ::iterator it;

set ::iterator temp;

while(q--)

else

y=0;

}} else

}return 0;

}

在來乙個標準並查集

#include #include using namespace std;

int a[1000100]; //容量a

int s[1000100]; //父親陣列 集合的根節點時當前節點往後第乙個未澆滿的節點

int cup[1000100]; //實際容量

void make_set(void) //初始化

int find(int x) //查詢

void union(int root1,int root2) //合併

else

y=0; }}

int main()

else

}return 0;

}

簡化後的並查集

#include using namespace std;

int p[100010];

int find(int x)

int main()

; int n,q,t,x;

long long y;

scanf ("%d",&n);

for (int i=1;i<=n;i++)

p[n+1]=-1;

a[n+1]=1<<29;

scanf ("%d",&q);

while (q--)

if (x!=n+1)

cup[x]+=y;

} else

}return 0;

}

資料結構作業

一,思維導圖 二,概念筆記 1,在計算時間複雜度的時候一般有 o 1 2 n 2,在計算平均時間複雜度時對p i t i 求和,其中p i 是概率,t i 是每個i的時間複雜度。3,儲存密度等於節點中個元素所佔的儲存量除以結點所佔的儲存量,儲存密度越大儲存空間的利用率越高。4,每次出棧只能出棧棧頂元...

資料結構作業 2

題目 設有乙個線性表 a0,a1,an 2,an 1 存放在單鏈表中。試編寫乙個演算法將該線性表原地逆置,即利用原結點空間置換為 an 1,an 2,a1,a0 並分析該演算法的時間複雜度。1 需求分析 1 用單鏈表存放乙個線性表 a0,a1,an 2,an 1 2 將該線性表原地逆置,即利用原結點...

資料結構作業 7

題目 編寫遞迴演算法,計算二叉樹中葉子結點的數目。1 需求分析 使用遞迴的方法,實現二叉樹中葉子節點數量的計算。輸入 一顆樹的前序遍歷,用 代替結束符。例如,前序遍歷 ab c d 輸出 二叉樹的葉子節點個數。功能 計算輸入的二叉樹的葉子節點個數。2 概要設計 二叉樹定義 資料 左孩子 或為空,或為...