演算法與資料結構實驗題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 概要設計 二叉樹定義 資料 左孩子 或為空,或為...