# 演算法課程題解 - 陣列
# UVa 591
## 題目
http://domen111.github.io/UVa-Easy-Viewer/?591
給一排疊得高高的積木群,現在我們要把他們得高度都變一樣,而每次我們可以將任意得一塊積木移動到另一排積木上
問最小移動次數,使得積木得高度能完全相同
## 解法 By Koios1143
### 想法
既然可以任意移動積木,那麼我們只需要關心高度高於平均值的積木堆,並將他們的積木平均給矮的積木堆
至於怎麼分給積木堆並不是我們關心的,所以我們只需要計算有哪些積木是需要移動的即可
### 程式碼
```cpp=
#include<iostream>
using namespace std;
int arr[55];
int cnt,n,ans,Case=1;
int main(){
while(cin>>n && n){
cnt=0;
ans=0;
for(int i=0 ; i<n ; i++){
cin>>arr[i];
cnt+=arr[i];
}
cnt/=n;
for(int i=0 ; i<n ; i++){
if(arr[i]>cnt)
ans+=(arr[i]-cnt);
}
cout<<"Set #"<<Case++<<"\n";
cout<<"The minimum number of moves is "<<ans<<".\n\n";
}
return 0;
}
```
### 時間複雜度分析
每筆測資輸入時間複雜度為 $O(n)$
找答案的時間複雜度為 $O(n)$
每筆測資總時間複雜度為 $O(2n)$ 約為 $O(n)$
# UVa 10963
## 題目
http://domen111.github.io/UVa-Easy-Viewer/?10963
再東西向上有一群南北向的裂縫,對於每群裂縫我們可以把他們南北向任意移動
當所有裂縫的高度都相同時,裂縫就不存在了
現在給你每個裂縫的 $(y_1,y_2)$ ,求是否可以將裂縫補齊
## 解法 By Koios1143
### 想法
題目的意思其實就是因為可以任意移動,只要所有的裂縫高度都相同,那裂縫就能補齊
那麼我們只需要判斷是不是所有的高度都相同即可
拿一個變數去紀錄有出現過的高度,當有裂縫的高度跟他不同時,答案就會是 `no` ,所有高度都相同時為 `yes`
### 程式碼
```cpp=
#include<iostream>
#include<cmath>
using namespace std;
int n,m;
int main(){
cin>>n;
bool out=false;
while(n--){
if(out) cout<<"\n";
else out=true;
cin>>m;
int cnt=-1; // 紀錄高度
bool done=true;
for(int i=0,x,y ; i<m ; i++){
cin>>x>>y;
if(cnt==-1) cnt=abs(x-y);
else if(cnt!=abs(x-y))
done=false;
}
if(done)
cout<<"yes\n";
else
cout<<"no\n";
}
return 0;
}
```
### 時間複雜度分析
每筆測資輸入與計算高度時間複雜度為 $O(m)$
每筆測資總時間複雜度為 $O(m)$
# UVa 11059
## 題目
http://domen111.github.io/UVa-Easy-Viewer/?11059
給一個序列,問最大連續元素的乘積
## 解法 By Koios1143
### 想法
因為這題的 $N$ 很小,所以可以直接暴力做
枚舉開頭跟結尾,將其中的元素乘起來,並找出最大值
注意乘積可以到 $10^{18}$ ,記得開 long long
### 程式碼
```cpp=
#include<iostream>
using namespace std;
int n,arr[20],Case=1;
long long ans,tmp;
int main(){
while(cin>>n){
for(int i=0 ; i<n ; i++){
cin>>arr[i];
}
ans=0;
for(int i=0 ; i<n ; i++){
// i 表示開頭
tmp=1;
for(int j=i ; j<n ; j++){
// j 表示結尾
tmp*=arr[j];
ans=max(ans,tmp);
}
}
cout<<"Case #"<<Case++<<": The maximum product is "<<ans<<".\n\n";
}
return 0;
}
```
### 時間複雜度分析
每筆測資輸入時間複雜度為 $O(n)$
枚舉答案的時間複雜度為 $O(n^2)$
每筆測資總時間複雜度為 $O(n+n^2)$ 約為 $O(n^2)$
# ZJ b840
## 題目
https://zerojudge.tw/ShowProblem?problemid=b840
給一個 $n \times n$ 的陣列,求最大矩形和
## 解法 By Koios1143
### 想法
暴力枚舉左上角的點以及長寬,將答案加總後取最大值
因為本題題目範圍很小可以這樣做
### 程式碼
```cpp=
//By Koios1143
#include<iostream>
using namespace std;
int n,arr[25][25],ans=0,cnt=0;
int main(){
cin>>n;
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<n ; j++){
cin>>arr[i][j];
}
}
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<n ; j++){
for(int k=0 ; k+i<n ; k++){
for(int l=0 ; l+j<n ; l++){
cnt=0;
for(int p=i ; p<=i+k ; p++){
for(int q=j ; q<=j+l ; q++){
cnt+=arr[p][q];
}
}
ans=max(cnt, ans);
}
}
}
}
cout<<ans<<"\n";
return 0;
}
```
### 複雜度分析
總時間複雜度為 $O(n^2 + n^6)$
###### tags: `SCIST 演算法 題解`