因為昨天在巴哈上看到
日音醬提到他在校內選拔無法解出這兩題
所以我就決定要來解解看這兩題
剛好也是以往北市賽的題目 就順便練一下吧
TIOJ 2008 - 格鬥大賽 (Fight)
這題的想法還滿簡單的 就是要去找每個編號最多能夠贏多少人
很直接的就是要去找所有編號勝場數最大的
不過如果我們直接暴搜 複雜度會是 $O(n^2)$
因此 我們需要想到別的方式來維護每個編號的最大值
我們可以很輕易的想到 如果一個人能夠贏過 $x$ 個人
那麼打贏這人的人一定能夠贏過 $x$ 個人以上
這裡用 $w$ 表示每個人的勝場數
我們可以知道若第 $i$ 個人贏過第 $j$ 個人 ($j$ < $i$)
且 $i$ 贏過 $i-1,i-2,…, j$個人
那麼 $w_i = w_j + (i-j-1)$
我們可以利用 stack 來維護這個值
或者不使用 stack 直接使用迴圈也可解出這題
1 |
|
TIOJ 2009 - 數字密碼鎖
這題感覺就是當年的送分題
這題沒什麼難度
我們先紀錄一開始陣列與最後目標的陣列的數字差
再貪心的由前而後將數字差變為零
當最後有一個或以上數字差不為零 則沒有答案
程式碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using namespace std;
signed main(){
fastio
int n,k;
cin >> n >> k;
int arr[n];
for(auto &x : arr) cin >> x;
for(int i = 0,tmp;i < n;i++){
cin >> tmp;
if(tmp < arr[i]) arr[i] = tmp+9-arr[i];
else arr[i] = tmp-arr[i];
}
int ans = 0;
for(int i = 0;i <= n-k;i++){
if(arr[i]==0) continue;
int tmp = arr[i];
ans += tmp;
for(int j = 0;j < k;j++){
arr[i+j] = (arr[i+j]-tmp+9)%9;
}
}
for(int i = 0;i < n;i++){
if(arr[i]!=0){
cout << 0 << "\n";
return 0;
}
}
cout << ans << "\n";
}
心得
這兩題感覺難度都不太高
希望今年的題目不要太難 然後想進全國賽 QQ