---
# System prepended metadata

title: '**APCS程式選修**'
tags: [C/C++, APCS]

---

# **APCS程式選修**

這些是本學期在程式選修上課時，自己練習實作題時，有完成的程式碼。

## 心得
覺得有些程式碼應該能更簡化且讓記憶體使用的更少，以達到縮時，像是費氏數列，自己在寫其他類似的題目時很容易就超時(TLE)，導致測資不通過。

## 題庫
- [秘密差](#秘密差)
- [排隊](#排隊)
- [費氏數列-遞迴](#費氏數列-遞迴)
- [最後倒數](#最後倒數)
- [找最大值](#找最大值)
- [特殊編碼](#特殊編碼)

## 秘密差
題目來源:[ZJ c290](https://zerojudge.tw/ShowProblem?problemid=c290)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
string x;
int a,b;
int main(){
    cin>>x;
    int len=x.length();
    for(int i=0;i<len;i++){
        if(i%2!=0)a=a+x[i]-48;
        else b=b+x[i]-48;
    }
    cout<<abs(a-b)<<endl;
}
```
想法:
分別計算奇數位和偶數位的總和，再相減取絕對值(abs)，因為ASCII碼，所以讀進來的數字要減48。

## 排隊
題目來源:[GJ c049](http://www.tcgs.tc.edu.tw:1218/ShowProblem?problemid=c049)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
//by icerain
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n,sum;
cin>>n;
int a[n],b[n],c[n];
for(int i=0;i<n-1;i++){
	cin>>a[i]>>b[i];
}
c[0]=a[0];
for(int j=1;j<n;j++){
	if(a[j]==b[j-1]){
		c[j]=a[j];
	}
}
c[n-1]=b[n-2];
sum=c[0]%997;
for(int k=1;k<n;k++){
	sum=(sum*7+c[k])%997;
}
cout<<sum;
return 0;
}
```
想法:
以第一個輸入的數字為開頭，開始循序搜尋去排出完整的陣列後再做計算。

## 費氏數列-遞迴
題目來源:[GJ b022](http://www.tcgs.tc.edu.tw:1218/ShowProblem?problemid=b022)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
int sum=0;
long long f(int n){
    sum++;
    if(n==0)return 0;
    if(n==1)return 1;
        return f(n-1)+f(n-2);
    
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0); 
    int n;
    cin>>n;
    cout<<f(n)<<" ";
    cout<<sum<<endl;
}
```
想法:
直接套用常用的費氏數列的遞迴函式，再加以改寫。
費氏數列:
```cpp=
#include<bits/stdc++.h>
using namespace std;
long long F[1000005];
long long f(int n){
	if(n==1)return 1;
	if(n==2)return 2;
	if(F[n])return F[n];
	return F[n]=f(n-1)+f(n-2);
}
int main(){
	int n;
	cin>>n;
	while(n!=0){
	cout<<f(n)<<endl;
	cin>>n;
	}
}
```
## 最後倒數
題目來源:[GJ b001](http://www.tcgs.tc.edu.tw:1218/ShowProblem?problemid=b001)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
long long n;
cin>>n;
long long a[n];
for(long long i=0;i<n;i++){
	cin>>a[i];
}
for(long long j=n-1;j>=0;j--){
	cout<<a[j]<<" ";
}
return 0;
}
```

想法:
單純使用一維陣列去紀錄，再由後往前輸出。

## 找最大值
題目來源:[GJ b002](http://www.tcgs.tc.edu.tw:1218/ShowProblem?problemid=b002)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
//by icerain
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin>>n;
int a[n];
int max=0,s;
for(int i=0;i<n;i++){
	cin>>a[i];
	if(a[i]>max){
	max=a[i];
	s=i+1;
	}
}
cout<<s<<" "<<max;
return 0;
}
```

想法:
一個一個循序比較，只記錄最大值跟在第幾個。

## 特殊編碼
題目來源:
![](https://i.imgur.com/tPjilg3.png)

程式:
```cpp=
#include<bits/stdc++.h>
using namespace std;
//by icerain
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
int a,b,c,d;
cin>>n;
for(int i=0;i<n;i++){
	cin>>a>>b>>c>>d;
	if(a){
		if(b){
			if(d)cout<<"D";
			else cout<<"F";
		}
		else cout<<"E";
	}
	else{
		if(b){
			if(c)cout<<"B";
			else cout<<"A";
		}
		else cout<<"C";
	} 
}
return 0;
}
```

想法:
每個字元都由四個0或1組成，所以從是0或是1為分支，慢慢去搜尋出來。
類似題:[ZJ e283](https://zerojudge.tw/ShowProblem?problemid=e283)


## 資料來源
題目都是老師給的，但是有備註在哪裡抓到的，APCS的題目則是能在ZERO JUDGE找到。

高中生程式解題系統(ZJ):https://zerojudge.tw/
台中女中程式解題系統(GJ):http://www.tcgs.tc.edu.tw:1218/

---
###### tags: `C/C++` `APCS`