P1:遊戲選角
印出「x 和 y 的平方和」第二大的 x 和 y。
ZeroJudge 連結
解法一:用 struct
#include <iostream>
#include <algorithm>
using namespace std;
struct Pair{
int x, y;
};
bool cmp(Pair a, Pair b){
return a.x * a.x + a.y * a.y > b.x * b.x + b.y * b.y;
}
int main(){
int n;
cin >> n;
Pair a[n];
for(int i=0; i<n; i++){
cin >> a[i].x >> a[i].y;
}
sort(a, a+n, cmp);
cout << a[1].x << ' ' << a[1].y << '\n';
}解法二:用 vector
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(vector<int> a, vector<int> b){
return a[2] > b[2];
}
int main(){
int n;
cin >> n;
vector<vector<int>> v(n, vector<int>(3));
for(int i=0; i<n; i++){
cin >> v[i][0] >> v[i][1];
v[i][2] = v[i][0] * v[i][0] + v[i][1] * v[i][1];
}
sort(v.begin(), v.end(), cmp);
cout << v[1][0] << ' ' << v[1][1] << '\n';
}P2:蜜蜂觀察
輸出蜜蜂經過的字母(碰到牆壁該行動會停在原地)。
ZeroJudge 連結
#include <iostream>
#include <string>
using namespace std;
int main(){
int m, n, k;
cin >> m >> n >> k;
char a[m][n];
string s;
for(int i=0; i<m; i++){
cin >> s;
for(int j=0; j<n; j++){
a[i][j] = s[j];
}
}
int nx = m-1, ny = 0, step, count = 0;
bool visited[58] = {false}; // 65~90, 97~122 -> 0~25, 32~57
int dx[6] = {-1, 0, 1, 1, 0, -1};
int dy[6] = {0, 1, 1, 0, -1, -1};
while(k--){
cin >> step;
if(nx + dx[step] >= 0 && nx + dx[step] < m && ny + dy[step] >= 0 && ny + dy[step] < n){
nx += dx[step];
ny += dy[step];
}
cout << a[nx][ny];
if(!visited[a[nx][ny]-65]){
visited[a[nx][ny]-65] = true;
count++;
}
}
cout << '\n' << count << '\n';
}P3:邏輯電路
求最大延遲時間、輸出端口的數值。
輸入端口 p 個 (編號 1 到 p)
邏輯閘 q 個 (編號 p+1 到 p+q)
輸出端口 r 個 (編號 p+q+1 到 p+q+r)
ZeroJudge 連結
使用到的觀念:【筆記】拓撲排序 (Topological Sort)
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct node {
int value;
int type;
vector<int> out;
vector<int> in;
int indegree;
int delay;
};
int main(){
int p, q, r, m;
cin >> p >> q >> r >> m;
vector<node> v(p+q+r);
for(int i=0; i<p; i++) cin >> v[i].value;
for(int i=p; i<p+q; i++) cin >> v[i].type;
while(m--){
int a, b;
cin >> a >> b;
a--, b--; // 0-based
v[a].out.push_back(b);
v[b].in.push_back(a);
v[b].indegree++;
}
queue<int> qu;
vector<int> ans;
for(int i=0; i<p+q+r; i++){
if(v[i].indegree == 0) qu.push(i);
}
while(!qu.empty()){
int now = qu.front();
ans.push_back(now);
qu.pop();
for(int i : v[now].out){
if(--v[i].indegree == 0) qu.push(i);
}
}
int maxDelay = 0;
for(int i : ans){
if(v[i].type == 1){ // AND
v[i].value = v[v[i].in[0]].value & v[v[i].in[1]].value;
v[i].delay = max(v[v[i].in[0]].delay, v[v[i].in[1]].delay) + 1;
}else if(v[i].type == 2){ // OR
v[i].value = v[v[i].in[0]].value | v[v[i].in[1]].value;
v[i].delay = max(v[v[i].in[0]].delay, v[v[i].in[1]].delay) + 1;
}else if(v[i].type == 3){ // XOR
v[i].value = v[v[i].in[0]].value ^ v[v[i].in[1]].value;
v[i].delay = max(v[v[i].in[0]].delay, v[v[i].in[1]].delay) + 1;
}else if(v[i].type == 4){ // NOT
v[i].value = 1 - v[v[i].in[0]].value;
v[i].delay = v[v[i].in[0]].delay + 1;
}
maxDelay = max(maxDelay, v[i].delay);
}
cout << maxDelay << '\n';
for(int i=p+q; i<p+q+r; i++){
cout << v[v[i].in[0]].value << ' ';
}
}P4:合併成本
挑兩個「相鄰」數字合併,花費 |u-v|,變成 u+v,求最小花費。
ZeroJudge 連結
解法:動態規劃 (DP)
cost[i][j] = 合併第 i 到 j 個數的最小花費
為了確保每一步的合併做出最佳選擇 → 遍歷尋找分割點
將 [i, j] 分割成 [i, k] 和 [k+1, j]
計算這兩部分分別合併成一個數字的花費,再加上最後合併這兩部分的額外花費。

#include <iostream>
#include <cstring>
using namespace std;
int a[100];
int cost[100][100];
int dp(int l, int r){
if(l == r) return 0;
if(cost[l][r] != -1) return cost[l][r];
int Min = 2000 * 99;
for(int k=l; k<r; k++){
int u = 0, v = 0;
for(int i=l; i<=k; i++) u += a[i];
for(int i=k+1; i<=r; i++) v += a[i];
Min = min(Min, dp(l, k) + dp(k+1, r) + abs(u - v));
}
cost[l][r] = Min;
return Min;
}
int main(){
int n;
cin >> n;
for(int i=0; i<n; i++){
cin >> a[i];
}
memset(cost, -1, sizeof(cost));
cout << dp(0, n-1) << '\n';
}