# 112上學期第一次社內賽題解 ## 癸卯事變 就...直接做 ```cpp= #include<bits/stdc++.h> using namespace std; long long a, b, c, d, e; int win; int main(){ cin >> a >> b >> c; if(a>b){ d=a*(a-b); win=1; } else{ d=b*(b-a); win=2; } if(c>d){ e=d*(c-d); win=3; } else e=c*(d-c); cout << '(' << win << ',' << e << ')'; } ``` ## LINK START 紀錄兩隊分數,記得要用 long long ```cpp= #include<bits/stdc++.h> using namespace std; int k; long long a, b, c, x=0, y=0; int main(){ cin >> k; while(k--){ cin >> a >> b >> c; x+=a*b; y+=a*c; } cout << x << '\n' << y << '\n'; if(x>y) cout << 0; else if(x<y) cout << 1; else cout << "tie"; } ``` ## 儲水管理 $mx$ 是最大高度,$p1, p2$ 是構成最大高度的兩面牆(編號最小),$nowh$ 是當前讀入的高度,$tmpp, tmph$ 為最高的牆編號和高度 因為最終要求編號最小,所以只有最大高度變大時才要換 ```cpp= #include<bits/stdc++.h> using namespace std; int n; long long mx=-1, p1=0, p2=0, nowh, tmpp=0, tmph=-1; int main(){ cin >> n; for(int i=1; i<=n; i++){ cin >> nowh; if(nowh>tmph){ if(tmph>mx){ mx=tmph; p1=tmpp; p2=i; } tmph=nowh; tmpp=i; } else if(nowh<tmph){ if(nowh>mx){ mx=nowh; p1=tmpp; p2=i; } } } cout << p1 << ' ' << p2; } ``` ## 晶石運送 先看懂題目,可以得出建在 $x$ 點的剩餘能量為下式 $\displaystyle\sum_{i=1}^{n}{(b_i-(x-a_i)^2)}$ $=\displaystyle\sum_{i=1}^{n}{b_i}-(nx^2-2(\displaystyle\sum_{i=1}^{n}{a_i})x+\displaystyle\sum_{i=1}^{n}{(a_i)^2})$ $=-n(x^2-2(\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})x+(\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})^2)+\displaystyle\sum_{i=1}^{n}{b_i}-\displaystyle\sum_{i=1}^{n}{(a_i)^2}+n(\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})^2$ 只看前面這塊找最大,即 $x^2-2(\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})x+(\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})^2$ 找最小 $=(x-\displaystyle\sum_{i=1}^{n}\frac{a_i}{n})^2$ 因此要找到整數 $x$ 最靠近 $\displaystyle\sum_{i=1}^{n}\frac{a_i}{n}$ 把 $\displaystyle\sum_{i=1}^{n}\frac{a_i}{n}$ 拆成整數和小數來看 因為程式當中整數除法會無條件捨去小數,因此整數部分是 $\lfloor\displaystyle\sum_{i=1}^{n}{\frac{a_i}{n}}\rfloor$ (程式中的整數除法),小數部分絕對值是 $\cfrac{|\displaystyle\sum_{i=1}^{n}{a_i}|\%n}{n}$ 我們可以先讓 $x=\lfloor\displaystyle\sum_{i=1}^{n}{\frac{a_i}{n}}\rfloor$ 然後看小數部分 如果小數部分絕對值 $\cfrac{|\displaystyle\sum_{i=1}^{n}{a_i}|\%n}{n}\le\cfrac{1}{2}$,$x$ 就不用改變($x$ 比較靠近 $\displaystyle\sum_{i=1}^{n}{\frac{a_i}{n}}$) 也就是說判斷 $2 \times (|\displaystyle\sum_{i=1}^{n}{a_i}|\%n)\le n$ 是否成立 否則如果 $2 \times (|\displaystyle\sum_{i=1}^{n}{a_i}|\%n)> n$,那就要加上 $\cfrac{|\displaystyle\sum_{i=1}^{n}{a_i}|}{\displaystyle\sum_{i=1}^{n}{a_i}}$(若 $\displaystyle\sum_{i=1}^{n}{a_i}$ 是正的,$\displaystyle\sum_{i=1}^{n}{\frac{a_i}{n}}$ 比較靠近 $x+1$;若 $\displaystyle\sum_{i=1}^{n}{a_i}$ 是負的,$\displaystyle\sum_{i=1}^{n}{\frac{a_i}{n}}$ 比較靠近 $x-1$) 找到 $x$ 之後,帶回第二行式子就好(輸入時先紀錄 $\displaystyle\sum_{i=1}^{n}{b_i}$、$\displaystyle\sum_{i=1}^{n}{a_i}$、$\displaystyle\sum_{i=1}^{n}{(a_i)^2}$) ```cpp= #include<bits/stdc++.h> using namespace std; int t, n; long long a, b, suma, sumb, suma_sq, x; int main() { cin >> t; while(t--){ suma=0, sumb=0, suma_sq=0; cin >> n; for(int i=0; i<n; i++){ cin >> a; suma+=a; suma_sq+=a*a; } for(int i=0; i<n; i++){ cin >> b; sumb+=b; } x=suma/n; if(suma>0&&(suma%n)*2>n) x++; else if((-suma%n)*2>n) x--; cout << sumb-n*x*x+2*suma*x-suma_sq << '\n'; } } ```