---
# System prepended metadata

title: 112年度學科能力競賽竹北高中校內初選題解

---

# 112年度學科能力競賽竹北高中校內初選題解
###### by ocean
------------------------------------
[題目](https://drive.google.com/file/d/1P4hZYuNl4UgONtiu3R-hFMxe1ZXCuGgP/view?usp=sharing)
## 第一題
排序後，隔一個分組
:::spoiler code
```c++=
#include<bits/stdc++.h>
#define int long long
using namespace std;

int32_t main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    int num[10];
    int a = 0, b = 0;
    for(int i=0;i<10;i++) cin>>num[i];
    sort(num, num+10);
    for(int i=0;i<10;i++){
        if(i % 2) b += num[i];
        else a += num[i];
    }
    cout<<b<<" "<<a<<"\n";

    return 0;
}
```
:::
## 第二題
因為本次比賽並無時間限制，所以硬爆是可行的:)
~~對 我硬爆我驕傲~~
但我可以提供一些想法
![](https://hackmd.io/_uploads/Hy7Po4wC2.png)
可以發現是外圈往內數的，並且每次皆為左上開始，可以依據這個規律寫出答案
:::spoiler 硬爆code
```c++=
#include<bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    int n, i, j;cin>>n>>i>>j;
    int num[n+1][n+1] = {};
    int op = 1;
    int x=1, y=1, k = 2;
    num[1][1] = 1;
    // cout<<(n/2 + (n % 2))<<" "<<(n / 2 + 1)<<"\n";
    while(y != (n/2 + (n % 2)) or x != (n / 2 + 1)){
        if(op == 1){
            if(y+1 <= n and num[x][y+1] == 0){
                y++;
                num[x][y] = k++;
            }else op++;
        }else if(op == 2){
            if(x+1 <= n and num[x+1][y] == 0){
                x++;
                num[x][y] = k++;
            }else op++;
        }else if(op == 3){
            if(y-1 > 0 and num[x][y-1] == 0){
                y--;
                num[x][y] = k++;
            }else op++;
        }else if(op == 4){
            if(x-1 > 0 and num[x-1][y] == 0){
                x--;
                num[x][y] = k++;
            }else op=1;
        }
                // cout<<x<<" "<<y<<"\n";
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cout<<num[i][j]<<" ";
        }
        cout<<"\n";
    }*/
    cout<<num[i][j]<<"\n";

    return 0;
}
```
:::
## 第三題
利用while(cin>>)迴圈或者getline(cin, )簡單模擬
:::info
分數加法公式
a/b + c/d = (a\*d + b\*c)/b\*d 
:::
:::spoiler code
```c++=
#include<bits/stdc++.h>
#define int long long
#define f first
#define s second
using namespace std;

pair<int, int> a;
string s;
char op;

int32_t main(){
    // ios::sync_with_stdio(0);
    // cin.tie(0);cout.tie(0);

    cin>>s;
    int i=0;
    for( ;i<s.size() and isdigit(s[i]);i++){
        a.f *= 10;
        a.f += s[i] - '0';
    }
    i += 1;
    for( ;i<s.size() and isdigit(s[i]);i++){
        a.s *= 10;
        a.s += s[i] - '0';
    }
    // cout<<a.f<<" "<<a.s<<"\n";
    while(cin>>op){
        cin>>s;
        pair<int,int> b;
        int i=0;
        for( ;i<s.size() and isdigit(s[i]);i++){
            b.f *= 10;
            b.f += s[i] - '0';
        }
        i += 1;
        for( ;i<s.size() and isdigit(s[i]);i++){
            b.s *= 10;
            b.s += s[i] - '0';
        }
        // cout<<a.f<<" "<<a.s<<" "<<b.f<<" "<<b.s<<"\n";
        if(op == '+'){
            a.f = a.f*b.s + a.s*b.f;
            a.s = a.s * b.s;
        }else if(op == '-'){
            a.f = a.f*b.s - a.s*b.f;
            a.s = a.s * b.s;
        }
        int p = __gcd(a.f, a.s);
        a.f /= p;
        a.s /= p;
        if(a.s < 0){
            a.s *= -1;
            a.f *= -1;
        }

    }
    cout<<a.f<<"/"<<a.s<<"\n";

    return 0;
}
```
:::
## 第四題
dp經典題，也可以說是費氏數列加強版
dp[0] = 1
dp[1] = 1
dp[2] = 2
dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
:::spoiler code
```c++=
#include<bits/stdc++.h>
#define int long long
using namespace std;

int32_t main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    int n;cin>>n;
    int dp[n+1] = {};
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 2;
    for(int i=3;i<=n;i++) dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
    cout<<dp[n]<<"\n";

    return 0;
}
```
:::
## 第五題
題目中說道
![](https://hackmd.io/_uploads/Hyyq6NDCh.png)
很明顯就算有限時間硬爆也是一個可行解
利用next_permutation排出所有運算符號的運算順序
最好的方法是利用struct實作
~~但因為我懶，所以使用set實作~~
:::spoiler code
```c++=
#include<bits/stdc++.h>
#define int long long
using namespace std;

string s;
int ans = -1e9;
char op[50];
int ord[50];
vector<int> num(51);

int32_t main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    for(int i=0;i<50;i++) ord[i] = i;
    cin>>s;
    int i=0;
    for( ;i<s.size() and isdigit(s[i]);i++){
        num[0] *= 10;
        num[0] += s[i] - '0';
    }
    int a = 1, b = 0;
    for( ;i<s.size();i++){
        if(isdigit(s[i])){
            for( ;i<s.size() and isdigit(s[i]);i++){
                num[a] *= 10;
                num[a] += s[i] - '0';
            }
                        a++;
            i--;
        }else op[b++] = s[i];
    }
        // cout<<a<<" "<<b<<"\n";
        // for(int i=0;i<a;i++) cout<<num[i]<<" ";
        // cout<<"\n";
        // for(int i=0;i<b;i++) cout<<op[i]<<" ";
        // cout<<"\n";
    do{
        // for(int i=0;i<50;i++) cout<<ord[i];
        // cout<<"\n";
        set<int> st;
        vector<int> tmp = num;
        for(int i=0;i<=b;i++) st.insert(i);
        for(int i=0;i<b;i++){
            auto it = st.lower_bound(ord[i]);
            if(op[*it] == '-') tmp[(*next(it))] = tmp[(*it)] - tmp[(*next(it))];
            else if(op[*it] == '+') tmp[(*next(it))] = tmp[(*it)] + tmp[(*next(it))];
            else if(op[*it] == '*') tmp[(*next(it))] = tmp[(*it)] * tmp[(*next(it))];
            st.erase(ord[i]);
                        // for(int i:st) cout<<tmp[i]<<" ";
                        // cout<<"\n";
        }
               
        ans = max(tmp[b], ans);
    }while(next_permutation(ord, ord+b));

    cout<<ans<<"\n";

    return 0;
}
```
:::