---
# System prepended metadata

title: APCS202201

---

# APCS202201
#### 以下非*施工中*程式碼皆由ZeroJudge檢測通過
## [1. 程式交易](https://zerojudge.tw/ShowProblem?problemid=h081)
紀錄前一次交易的價格&是否有股票
硬算
:::spoiler C++
```cpp=
#include <iostream>
using namespace std;
int main(){
    int n,d,last,cur,had=0,ans=0;
    cin >> n >> d;
    cin >> cur;
    last = cur;
    had=1;
    n--;
    while(n--){
        cin >> cur;
        if (had){
            if (cur>=last+d){
                had = 0;
                ans+=cur-last;
                last = cur;
            }
        }else{
            if (cur<=last-d){
                had = 1;
                last = cur;
            }
        }
    }
    cout << ans << "\n";
}
```
:::
:::spoiler Python
```python=
n,d = map(int,input().split())
last=10000
had=False
ans=0
for cur in map(int,input().split()):
    if had:
        if cur>=last+d:
            had=False
            ans+=cur-last
            last=cur
    else:
        if cur<=last-d:
            had=True
            last=cur
print(ans)
```
:::
:::spoiler Python in one line
```python=
print((lambda a,l:(lambda n,d,v:max(((bool(v.__setitem__(0,v[0]+c-v[1]))+bool(v.__setitem__(1,c))+bool(v.__setitem__(2,False)) if c>=v[1]+d else 0) if v[2] else (bool(v.__setitem__(1,c))+bool(v.__setitem__(2,True)) if c<=v[1]-d else 0) for c in l))+v[0])(int(a[0]),int(a[1]),[0,10000,False]))(input().split(),map(int,input().split())))
```
:::
## [2. 贏家預測](https://zerojudge.tw/ShowProblem?problemid=h082)
照題敘算
:::spoiler C++
施工中
```cpp=
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m;
    cin >> n >> m;
    vector<int> s(n),t(n),o(n),h(n,m);
    for (int i = 0;i<n;i++){
        cin >> s[i];
    }
    for (int i = 0;i<n;i++){
        cin >> t[i];
    }
    for (int i = 0;i<n;i++){
        cin >> o[i];
        o[i]++;
    }
    while (o.size()>1){
        vector<int> ns(n,0),nt(n,0),win,lose;
        for (int i = 0;i<o.size()/2;i++){
            int a = o[i*2];
            int b = o[i*2+1];
            if (s[b]*t[b]>s[a]*t[a]){
                swap(a,b);
            }
            h[b]--;
            ns[a] = s[b]*t[b]/t[a]/2;
            nt[a] = s[b]*t[b]/s[a]/2;
            ns[b] = s[b]/2;
            nt[b] = t[b]/2;
            win.push_back(a);
            if(h[b]) lose.push_back(b);
        }
        for (int i = 0;i<n;i++){
            s[i]+=ns[i];
            t[i]+=nt[i];
        }
        o.clear();
        for (int p : win){
            o.push_back(p);
        }
        for (int p : lose){
            o.push_back(p);
        }
    }
    cout << (o[0]+1) << "\n";
}
```
:::
:::spoiler Python
```python=
n,m = map(int,input().split())
s = [int(text) for text in input().split()]
t = [int(text) for text in input().split()]
health = [m]*n
o = [int(text)-1 for text in input().split()]
while len(o)>1:
    win=[True]*n
    for i in range(len(o)//2):
        p1=o[i*2]
        p2=o[i*2+1]
        p1,p2=(p1,p2) if s[p1]*t[p1]>=s[p2]*t[p2] else (p2,p1)
        d=s[p2]*t[p2]//2
        s[p1],t[p1]=s[p1]+d//(t[p1]),t[p1]+d//(s[p1])
        s[p2]+=s[p2]//2
        t[p2]+=t[p2]//2
        health[p2]-=1
        win[p2]=False
    o = [i for i in o if win[i]]+[i for i in o if not win[i] and health[i]]
print(o[0]+1)
```
:::
:::spoiler Python in one line
```python=
print((lambda d:(lambda f:f(f,[d[1]]*d[0]))(lambda F,h:bool((lambda win:(lambda ns,nt:min((bool(d[2].__setitem__(d[4][i],ns[i])) for i in range(len(ns))))+min((bool(d[3].__setitem__(d[4][i],nt[i])) for i in range(len(nt))))+min((bool(h.__setitem__(d[4][i],h[d[4][i]]-(0 if win[i] else 1))) for i in range(len(d[4]))))+bool(d.__setitem__(4,[d[4][i] for i in range(len(d[4])) if win[i]]+[d[4][i] for i in range(len(d[4])) if not win[i] and h[d[4][i]]>0])))([(d[2][d[4][i]] if win[i]>1 else d[2][d[4][i]]+d[2][d[4][i^1]]*d[3][d[4][i^1]]//d[3][d[4][i]]//2) if win[i]>0 else d[2][d[4][i]]+d[2][d[4][i]]//2 for i in range(len(d[4]))],[(d[3][d[4][i]] if win[i]==2 else d[3][d[4][i]]+d[2][d[4][i^1]]*d[3][d[4][i^1]]//d[2][d[4][i]]//2) if win[i] else d[3][d[4][i]]+d[3][d[4][i]]//2 for i in range(len(d[4]))]))([((i^1<len(d[4])) and (d[2][d[4][i]]*d[3][d[4][i]]>d[2][d[4][i^1]]*d[3][d[4][i^1]] or (d[2][d[4][i]]*d[3][d[4][i]]==d[2][d[4][i^1]]*d[3][d[4][i^1]] and i<(i^1))))+2*(i^1==len(d[4])) for i in range(len(d[4]))]))*0+(F(F,h[:]) if len(d[4])>1 else d[4][0]+1)))([int(t) for t in input().split()]+[[int(t) for t in input().split()],[int(t) for t in input().split()],[int(t)-1 for t in input().split()]]))
```
:::
## [3. 數位占卜](https://zerojudge.tw/ShowProblem?problemid=h083)
用hashset存籤
對於每一個籤，切出不同長度的前後綴，若前綴=後綴 且 剩下的部分能在set裡找到一樣的 則 答案+1
#### 原理：
對於一組聖筊$a+b$
不失一般性設$a$比較長
所以**a的前半**和**a的後半加b**一樣
設**a的前半**=c、**a的後半**=d
$a+b=(c+d)+b=((d+b)+d)+b=(d+b+d)+b$
可知$d$是$a$的前後綴
所以對每一支籤，切出不同長度的前後綴$d$，只要存在與剩下的部分相同的籤$b$，就可以組成**聖筊**
因為總是用長的籤去找短的籤，所以不用擔心重複算到的問題
:::spoiler C++
```cpp=
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin >> n;
    unordered_set<string> dat;
    while (n--){
        string s;
        cin >> s;
        dat.insert(s);
    }
    long long ans = 0;
    for (string s: dat){
        int l = s.size();
        for (int i = 1;i<(l+1)/2;i++){
            bool sus = true;
            for (int j = 0;j<i;j++){
                if (s[j]!=s[j+l-i]) sus=false;
            }
            if (sus){
                ans += dat.count(s.substr(i,l-2*i))?1:0;
            }
        }
    }
    cout << ans << "\n";
}
```
:::
:::spoiler Python
```python=
m = int(input())
dat = {input() for a in range(m)}
ans = 0
for s in dat:
    for i in range(1,(len(s)+1)//2):
        if s[:i]==s[-i:] and s[i:-i] in dat:
            ans+=1
print(ans)
```
:::
:::spoiler Python in one line
```python=
print((lambda dat:str(sum((sum((s[:i]==s[-i:] and s[i:-i] in dat for i in range(1,(len(s)+1)//2))) for s in dat))))({input() for z in range(int(input()))}))
```
:::
## [4. 牆上海報](https://zerojudge.tw/ShowProblem?problemid=h084)
用貪心法可$O(n)$求出某一高度能否貼海報
能否貼海報$\leftrightarrow$此高度$\le$最大高度$=$答案
且已知答案為$[1,h_{max}]$中的一個整數
對$[1,h_{max}]$二分搜
時間複雜度為$O(n\log_2h_{max})$
:::spoiler C++
```cpp=
#include <bits/stdc++.h>
using namespace std;
int n,k;
vector<int> h,w;
bool check(int ans){
    int t = 0,len=0;
    for (int i = 0;i<n;i++){
        if (h[i]>=ans) len++;
        else len = 0;
        if(len>=w[t]){
            len-=w[t];
            t++;
            if(t>=k) return true;
        }
    }
    return false;
}
int search_ans(int l, int r){
    if (l == r) return l;
    int mid = ((r+l)/2)+1;
    if (check(mid)){
        return search_ans(mid,r);
    }
    return search_ans(l,mid-1);
}
int main(){
    ios::sync_with_stdio(false);cin.tie();
    cin >> n >> k;
    h.resize(n);
    w.resize(k);
    int mh = 0;
    for (int i = 0;i<n;i++){
        cin>>h[i];
        if(h[i]>mh) mh=h[i];
    }
    for (int i = 0;i<k;i++){
        cin>>w[i];
    }
    cout << search_ans(1,mh) << "\n";
}
```
:::
:::spoiler Python
```python=
n=k=0
h=[]
w=[]
def check(ans):
    t = l = 0
    for i in range(n):
        if h[i]>=ans:
            l+=1
        else:
            l=0
        if l>=w[t]:
            l-=w[t]
            t+=1
            if t>=k:
                return True
    return False
def search(l,r):
    if l==r:
        return l
    mid = (l+r)//2+1
    if check(mid):
        return search(mid,r)
    return search(l,mid-1)
n,k = map(int,input().split())
h = [int(s) for s in input().split()]
w = [int(s) for s in input().split()]
print(search(1,max(h)))
```
:::
:::spoiler Python in one line
```python=
print((lambda _0,h,w:(lambda c,f:str(f(1,max(h),f,c)))((lambda a:(lambda v:min((bool(v.__setitem__(1,v[1]+1 if i>=a else 0))+(bool(v.__setitem__(1,v[1]-w[v[0]]))+bool(v.__setitem__(0,v[0]+1)) if v[1]>=w[v[0]] else 0) for i in h if v[0]<len(w)))*0+(v[0]>=len(w)))([0,0])),(lambda l,r,F,C:l if l==r else (F((l+r)//2+1,r,F,C) if C((l+r)//2+1) else F(l,(l+r)//2,F,C)))))(input(),[int(s) for s in input().split()],[int(s) for s in input().split()]))
```
:::