---
title: 基礎程式設計
tags: 資訊
---
# C++基本語法
* **英文大小寫視為不同**的文字
* **盡量不要在程式碼裡面寫中文**,有時候會出錯。
* 有些**特定單字不能使用**,因為**被設為常用函數**,如**max**
可以打成**maxx**
* 將程式碼**放入{ }中**,就會**由上到下執行**,一旦執行到**return 0 ;**,程式就會**立刻結束。**
* 如果程式碼**只有一行,分號;可以省略**
* 句子的結尾要有 **分號 ;** ,代表一件事結束 **endl** 代表 end line,結束一行(**換行**)
* 使用**Tab**鍵 程式碼可以**縮排** **Enter鍵** 可以**換行**
* 當程式**無法執行時,可以設定端點進行Debug除錯**
## 一、CH1 變數與運算子
1. ### d483 hello, world
```c==
#include <iostream>
using namespace std;
int main()
{
cout << "hello, world";
return 0;
}
```
3. ### ★ a001 哈囉
:::info
- 要加while() 進行重覆運算
:::
```c==
#include <iostream>
using namespace std;
int main()
{
string s ;
while(cin >> s)
{
cout << "hello, "<< s << endl;
}
return 0;
}
```
3. ### a002 簡易加法
4. ### d489 伏林的三角地
5. ### ★ d827 買鉛筆
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
cout<< n/12*50+n%12*5<< endl;
}
return 0;
}
```
7. ### ★ d060 還要等多久啊?
```c==
#include <iostream>
using namespace std;
int main()
{
int m;
while(cin>> m)
cout<< (m<=25? 25-m: 25-m+60)<< endl;
return 0;
}
```
9. ### d485 我愛偶數
10. ### ★ d051 糟糕,我發燒了
```c==
#include <iomanip>
using namespace std;
int main()
{
int f;
while(cin>> f)
{
cout<< fixed << setprecision(3) <<(f-32)/1.8 << endl;
}
return 0;
}
```
12. ### ★ b004 繩子上吃草的牛
```c==
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
double D,L,s,l;
const double PI=2*acos(0);
while(cin>> D>> L)
{l=L/2;
s=sqrt(L/2*L/2-D/2*D/2);
printf("%.3f\n",PI*s*l);
return 0;
}
}
```
:::info
- printf .n控制小數點位數
:::
14. ### ★ d039 11044 - Searching for Nessy
### 作業
1. ### a861 1.Secure the Perimeter
:::info
- 2h+2w(*不能省略),(h+w)*2
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int h,w;
while(cin>>h>>w)
cout<<(2*h+2*w)<<endl;
return 0;
}
```
2. ### d226 10071 - Back to High School Physics
:::info
- v-t 圖算面積
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int v,t;
while(cin>>v>>t)
cout<<(v*t*2)<<endl;
return 0;
}
```
3. ### d053 Big Chocolate
:::info
- 3x4巧克力需要11刀
- m-1+m*(n-1) (why?)
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int m,n;
while(cin>>m>>n)
cout<<(m-1+(n-1)*m)<<endl;
return 0;
}
```
4. ### d277 矩陣對角線
:::info
- 3元運算子、%
對角線奇數可共用對角線交叉的花盆,偶數不共用
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
cout<<(n%2==1? n-1:n)<<endl;
}
return 0;
}
```
5. ### b681 1. 山洞探險
:::info
- 3元運算子
向北公式為2L-1,向南為2L
long long int
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int d,l;
while(cin>>l)
cout<<(l<0? -l*2:l*2-1)<<endl;
return 0;
}
```
6. ### d127 二、牧場面積
:::info
- 接近正方型面積會最大
long long int
周長減掉兩個寬剩兩個長
:::
```C==
#include <iostream>
using namespace std;
long long int L;
int main()
{
while(cin>>L)
{
cout <<(L/4)*((L-(L/4)*2)/2) << endl;
}
return 0;
}
```
7. ### d461 班際籃球賽
:::info
- 場數差低於1場 所以要打至多
:::
```c==
#include <iostream>
using namespace std;
int n;
int main()
{
while(cin>>n)
{
cout <<(n-1)<< endl;
}
return 0;
}
```
8. ### d096 00913 - Joana and the Odd Numbers
:::info
- long long int
有N個奇數為第(N+1)/2列
找出此列最後3個數字與第(N+1)/2列的關係
:::
```c==
cin >> t;
while(t>0)
{
....
t--;
}
或
while(t--)
{
....
}
```
```c==
#include <iostream>
using namespace std;
long long int a,n;
int main()
{
while()
{
cin>>n;
if(n%2=1)
(n+1)/2=a;
cout << (9+6*a) <<endl;
else()
n/2=a;
cout << (9+6*a) <<endl;
}
return 0;
}
```
9. ### c776 106北二1.六邊形屋瓦
:::info
- 扣掉重覆的白色屋瓦。
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int m,n,x ;
while (cin >> n>> m)
{
x= n*m*3+n*2+m*1;
cout << x <<endl;
}
return 0;
}
```
10. ### d549 矩形中的几何
:::info
- PA^2^ + PC^2^ = PB^2^ + PD^2^ (畢氏定理)
sqrt(),需 #include <cmath>
printf小數點,需 #include <cstdio>
PA、PB、PC變數形態用long long int或double
:::
```c==
#include<iostream>
using namespace std;
int main()
{
int T,a,b,sum,f=0;
while(cin>>T)
{
for(int i=0;i<T;i++)
{f++;sum=0;
cin>>a>>b;
for(int n=a;n<=b ;n++)
{
if(n%2!=0)
sum+=n;
}
cout<<"Case "<<f<<':'<<' '<<sum<<endl;
}
}
}
```
## 二、CH2 條件判斷
1. ### ★ a012 10055 - Hashmat the Brave Warrior
2. ### ★ d058 BASIC 的 SGN 函數
3. ### ★ d065三人行必有我師
```c==
#include <iostream>
using namespace std;
int a,b, c;
int main()
{
while(cin>> a >> b >> c)
{
if(a>b && a>c)
{
cout << a << endl;
}
else
{
if(b>c)
{
cout<< b <<endl;
}
else
{
cout<< c <<endl;
}
}
}
return 0;
}
```
:::info
- if條件是可以重複加入
:::
4. ### ★ a053 Sagit's 計分程式
```c==
#include <iostream>
using namespace std;
int a;
int main()
{
while(cin>> a )
{
if(a>=0&&a<=10)
cout << a*6 << endl;
else if(a<20)
cout<< 60+(a-10)*2 <<endl;
else if(a<=40)
cout<< 80+(a-20) <<endl;
else
cout<< 100 <<endl;
}
return 0;
}
```
5. ### a006 一元二次方程式
6. ### ★ d984 棄保效應
```c==
#include <iostream>
using namespace std;
unsigned int a, b, c;
int main()
{
while(cin>> a >> b>> c )
{
// a>b>c b>a>c c>a>b
if( a>b+c || b>a&&a>c&&a+c>b || c>a&&a>b&&a+b>c)
cout << "A" << endl;
// b>a>c a>b>c c>b>a
else if(b>a+c || a>b&&b>c&&b+c>a || c>b&&b>a&&b+a>c)
cout<< "B" <<endl;
else
cout<< "C" <<endl;
}
return 0;
}
```
7. ### ★ a004 文文的求婚
:::info
- 閏年為可被4整除且不被100整除,或可被400整除
:::
```c==
#include <iostream>
using namespace std;
unsigned int a;
int main()
{
while(cin>>a)
{
if( a%4==0&&a%100!=0 ||a%400==0)
cout << "閏年\n";
else
cout<< "平年\n";
}
return 0;
}
```
### 作業
1. ### d064 ㄑㄧˊ 數?
:::info
- 比較運算子
==(等於)
!=(不等於)
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int a ;
while(cin>> a)
{
if(a%2==1)
{
cout << "Odd" << endl;
}
else
{
cout << "Even" << endl;
}
}
return 0;
}
```
2. ### d066 上學去吧!
:::info
- 巢狀if
亦可將時化為分
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int a , b;
while(cin>> a >>b)
{
if(60*a+b>=450&&60*a+b<1020)
{
cout << "At School" << endl;
}
else
{
cout << "Off School" << endl;
}
}
return 0;
}
```
3. ### d460 山六九之旅
:::info
- 多項選擇
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int a ;
while(cin>> a )
{
if(a<6)
{
cout << "0" << endl;
}
else if(a>=6&&a<12)
{
cout << "590" << endl;
}
else if(a>=12&&a<18)
{
cout << "790" << endl;
}
else if(a>=18&&a<60)
{
cout << "890" << endl;
}
else if(a>=60)
{
cout << "399" << endl;
}
}
return 0;
}
```
4. ### a273 小朋友下樓梯
```c==
#include <iostream>
using namespace std;
int main()
{
int a , b ;
while(cin>> a >>b )
{
if(a>0&&b>0&&a%b==0){
cout << "Ok!" << endl;
}
else if(a>0&&b==0){
cout << "Impossib1e!" << endl;
}
else if(a==0&&b>0){
cout << "Ok!" << endl;
}
else if(a==0&&b==0)
cout << "Ok!" << endl;
else{
cout << "Impossib1e!" << endl;
}
}
return 0;
}
```
5. ### b186 97七區資訊學科1(改編)
:::info
- 取餅乾/10,蛋糕/2中小的數即是贈送的盒數
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int a , b ,c;
while(cin>> a >> b >> c)
{
if(a/10>c/2){
cout <<a<<" "<<"個餅乾,"<<b+(c/2)<<" "<<"盒巧克力,"<<c<<" "<<"個蛋糕。"<<endl;
}
else if(a/10==c/2){
cout <<a<<" "<<"個餅乾,"<<b+(a/10)<<" "<<"盒巧克力,"<<c<<" "<<"個蛋糕。"<<endl;
}
else {
cout <<a<<" "<<"個餅乾,"<<b+(a/10)<<" "<<"盒巧克力,"<<c<<" "<<"個蛋糕。"<<endl;
}
}
return 0;
}
```
6. ### a005 Eva 的回家作業
:::info
- 判斷等差或等比數列,求第5項
while(t\-\-)
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int t, a , b ,c , d ,e;
cin>>t;
while(t--)
{ cin>> a>> b >> c >> d >> e;
if(c-b==b-a){
cout <<a<<b<<c<<d<<d+b-a<<endl;
}
else if(c/b==b/a){
cout <<a<<b<<c<<d<<d*(b/a)<<endl;
}
}
return 0;
}
```
7. ### d057 11494 - Queen
:::info 垂直、水平、或對角線1步可到,其它2步可到
- abs()可求絕對值,需 #include <cstdlib>
if(x1 == 0 && y1 == 0 && x2 == 0 && y2 == 0) break;
或 if(!x1 && !y1 && !x2 && !y2) break; 讓輸入0 0 0 0時結束。
:::
```c==
#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int main()
{
int a, b , c , d ,e ,k;
while(cin>>a>>b>>c>>d)
{
if(abs(a-c)==abs(b-d))
{
pow(a-c,2)+pow(b-d,2)=e;
sqrt(e)=k;
}
else if(a-c==0)
{
abs(b-d)=k;
}
else if(b-d==0)
{
abs(a-c)=k;
}
else
abs(a-c)+abs(b-d)=k;
cout<< k << endl;
}
return 0;
}
```
8. ### d095 00579 - ClockHands
:::info
- 分別計算時針與分針相對於12點的角度再相減
fabs()可求浮點數的絕對值,需 #include <cmath>``` javascript
char colon; //設一個字元變數,把冒號讀掉
while( cin >> h >> colon >> m && !(h == 0 && m == 0) )```
:::
9. ### c461 apcs 邏輯運算子(Logic Operators)
:::info
- 位元運算子&(AND)、|(OR)、(^)XOR
將a、b以位元運算子運算後和c比較
:::
10. ### d502 第三題:產品包裝
:::info
- 裝3\*3\*3產品和2\*2\*2產品剩下的空間,用來裝1\*1\*1的產品,可讓需要的包裝箱最少。
一個3\*3\*3產品裝在箱子裏,會剩37個1\*1\*1的空間。
2\*2\*2產品裝在箱子裏,會剩64-8*(b%8)個1\*1\*1的空間。
小心n或k等於0的情形
:::
## 三、CH3 重複結構
1. ### ★ d490 我也愛偶數
```c==
#include <iostream>
using namespace std;
int main()
{
int a,b;
while(cin>> a>> b)
{
int sum=0;
for(int i=a;i<=b;i++)
{
if(i%2==0)
{
sum=sum+i;
}
}
cout << sum << endl;
}
return 0;
}
```
2. ### ★ d074 電腦教室
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>> n)
{
int maxx=-1,p;
for(int i=0;i<n;i++)
{
cin >> p;
if(p>maxx)
{
maxx=p;
}
}
cout << maxx << endl;
}
return 0;
}
```
4. ### ★ a215 明明愛數數
:::info
- do_while迴圈
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int m,n;
while(cin>> n >> m)
{
int sum=0,cnt=0;
do
{
sum+=n;
cnt++;
n++;
}
while(sum<=m);
cout << cnt << endl;
}
return 0;
}
```
7. ### ★ a024 最大公因數(GCD)
:::info
- 暴力法(i++ v.s. i\-\-)
* [時間複雜度1](https://medium.com/appworks-school/%E5%88%9D%E5%AD%B8%E8%80%85%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-%E8%AB%87%E4%BB%80%E9%BA%BC%E6%98%AF%E6%BC%94%E7%AE%97%E6%B3%95%E5%92%8C%E6%99%82%E9%96%93%E8%A4%87%E9%9B%9C%E5%BA%A6-b1f6908e4b80)、[時間複雜度2](https://jason-chen-1992.weebly.com/home/time-space-complexity)
- [輾轉相除法](http://www.mathland.idv.tw/fun/euclidean.htm) (a=bq+r,則gcd(a, b) = gcd(b, r))
- 除錯練習
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int n,m;
while(cin>> n >> m)
{
for(int i=min(n,m);i>=1;i--)
{
if(n%i==0&&m%i==0)
{
cout<< i <<endl;
break;
}
}
}
return 0;
}
```
```c==
#include <iostream>
using namespace std;
int main()
{
int a,b;
while(cin>> a >> b)
{
int r;
do{
r=a%b;
a=b;
b=r;
} while(r>0);
cout << a << endl;
}
return 0;
}
```
8. ### ★ a149 乘乘樂
:::info
- 運算子優先順序 sum=sum*(n%10)
- 複合指定運算子
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int t;
cin>> t;
while(t--)
{
int a,sum=1;
cin>>a;
do
{
sum*=a%10;
a/=10;
}while(a>0);
cout << sum << endl;
}
return 0;
}
```
10. ### ★ c418 Bert的三角形 (1)
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
for (int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
cout<< "*" ;
}
cout<<endl;
}
}
return 0;
}
```
11. ### ★c419 Bert的三角形 (2)
:::info
- 巢狀迴圈(內外圈變數不能重複)
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
for (int i=1;i<=n;i++)
{
for(int j=1;j<=n-i;j++)
{
cout<< "_" ;
}
for(int j=1;j<=i;j++)
{
cout<< "*" ;
}
cout<<endl;
}
}
return 0;
}
```
---
### 作業
1. ### d498 我不說髒話
:::info
- for迴圈
:::
```c=
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin >> n)
{
for( int i=1; i<=n; i++ )
{
cout << "I don't say swear words!" << endl;
}
}
return 0;
}
```
2. ### c022 10783 - Odd Sum
:::info
- 累加
:::
```c=
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int T,a,b,f=0,sum;
while(cin>>T)
{
for(int i=0;i<T;i++)
{
f++;
sum=0;
cin>>a>>b;
for(int n=a;n<=b;n++)
{
if(n%2!=0)
sum+=n;
}
cout<<"Case "<<f<<':'<<' '<<sum<<endl;
}
return 0;
}
}
```
3. ### d010 盈數、虧數和完全數
:::info
- 將因數累加
:::
```c==
#include <iostream>
using namespace std;
int main()
{
int N,sum=0;
while(cin >> N )
{
for(int i=1;i<N;i++)
{
if(N%i==0)
{
sum+=i;
}
}
if(sum>N)
{
cout << "盈數" << endl;
}
else if (sum==N)
{
cout << "完全數" << endl;
}
else if (sum<N)
{
cout << "虧數" << endl;
}
sum=0;
}
return 0;
}
```
4. ### c299 1. 連號或不連號
:::info
- 輸入數列時,找出其最大和最小值
最大-最小+1==n,表示這個數列是連續的
:::
5. ### d186 11461 - Square Numbers
:::info
- 完全平方數的判定
:::
6. ### a248 新手訓練 ~ 陣列應用
:::info
- 不斷的將a/b的餘數*10之後再除以b
:::
```c=
#include<iostream>
using namespace std;
int main()
{
int a,b,N;
while(cin>>a>>b>>N)
{
cout<<a/b<<'.';
a%=b;
for(int i=N;i>0;i--)
{
a*=10;
cout<<a/b;
a%=b;
}
cout<<endl;
}
return 0;
}
```
7. ### a038 數字翻轉
:::info
- while
不斷取個位數加入翻轉數字
:::
```c=
#include<iostream>
using namespace std;
int main()
{
int e;
while( cin >> e )
{
int abcde = 0;
while( e )
{
abcde *= 10;
abcde += e % 10;
e /= 10;
}
cout << abcde << endl;
}
return 0;
}
```
8. ### a536 11689 - Soda Surpler
:::info
- 每次換的汽水又可再變成空瓶子拿去換
可以換的汽水數量=所有空瓶數/c
手上空瓶=所有空瓶數/c+所有空瓶數%c
:::
9. ### d189 11150 - Cola
:::info
- 不論開始有幾瓶,最後的剩餘狀況都只1瓶或2瓶
:::
10. ### d122 Oh! My Zero!!
:::info
- 0的數量為2和5因數個數的較小值,對n!來說2的因數個數一定會比5多
:::
11. ### c420 Bert的三角形 (3)
:::info
- 巢狀迴圈
:::
12. ### c013 00488-Triangle Wave
:::info
- 巢狀迴圈
下半部 for(k=A-1;k>0;k\-\-)
:::
13. ### b003 運算式 + - 符號設定問題
:::info
- 1+2....+n=sum,如果減一個數字m,sum會減2*m
如果k-sum為偶數,則可從1~n找出數字減掉
[解題心得](https://home.gamer.com.tw/creationDetail.php?sn=4156133)
:::
<br />
## 四、CH4 陣列
1. ### ★ d212 東東爬階梯
:::info
- 一維陣列
- DP
- 費式數列
:::
```c=
#include <iostream>
using namespace std;
int main()
{
int n;
unsigned long long int f[100]={1,1}; //unsigned lon long int只能到f[92]
for(int i=2;i<100;i++)
f[i]=f[i-1]+f[i-2];
while(cin >> n)
cout << f[n] << endl;
return 0;
}
```
2. ### ★ c067 Box of Bricks
:::info
- 一維陣列
:::
```c=
#include <iostream>
using namespace std;
int main()
{
int n,Set=1;
while(cin >> n && n>0)
{
int h[n],sum=0,ave,mov=0;
for (int i=0;i<n;i++)
{
cin >> h[i];
sum+=h[i];
}
ave=sum/n;
for (int i=0;i<n;i++)
{
if(h[i]>ave)
{
mov+=(h[i]-ave);
}
}
cout << "Set #" << Set++ << endl << "The minimum number of moves is " << mov << "." << endl << endl;
}
return 0;
}
```
3. ### a693 吞食天地
:::info
- 每次都重算會TLE
- S[-1]陣列除錯
:::
```c==
#include <iostream>
#include <stdio.h>
int main()
int n,m;
int main()
{
while(cin>>n>>m)//輸入有幾筆測資 M行N個數字
{
int l,r;
int food[n+1]={0};
for(int i =1;i<=n;i++)
{
cin>>food[i];
food[i]+=food[i-1];//求總飽和度
}
//長的飽和度減掉短的飽和度就是所求飽和差
while(m--)
{
cin>>l>>r;
cout<<food[r]-food[l-1]<<endl;
}
}
return 0;
}
```
4. ### a020 身份證檢驗
:::info
- 以陣列將英文代號轉為數字
還有錯
:::
```c=
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)//輸入有幾筆測資 M行N個數字
{
int m,sum,x=8,f[n];
m=f[0]-55;
while()
{
cin>>f[i];
f[n]=f[i]+1;
f[n]=f[i]*x;
sum+=f[i];
x=x-1;
}
cout<< ((m/10)+sum)%10==0?"real":"fake"<<endl;
}
return 0;
}
```
5. ### b139 NOIP2005 2.校门外的树
6. ### ★ a104 排序
:::info
- [思考排序的演算法](https://zh.wikipedia.org/wiki/十三張)
- [insertion sort1](https://kopu.chat/2017/06/22/插入排序insertion-sort/)
- [insertion sort2](http://notepad.yehyeh.net/Content/Algorithm/Sort/Insertion/1.php)
- [insertion sort3](http://alrightchiu.github.io/SecondRound/comparison-sort-insertion-sortcha-ru-pai-xu-fa.html)
- [bubble sort](https://pjchender.blogspot.com/2017/09/bubble-sort.html)
:::
```c==
#include <iostream>
using namespace std;
unsigned int a, b, c;
int main()
{
int n,;
while(cin >> n )
{
int s[n];
for (int i=0;i<n;i++)
{
cin >> s[i];
}
for(int i=1;i<n;i++)
{
int
}
for(int i=0;i<n;i++)
{
cout << s[i] <<" ";
}
cout<< endl;
}
```
```c==
#include <iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)//測試筆數
{
int s[n]; //設置一個陣列
for(int i=0;i<n;i++)
cin>>s[i];//將數字讀入陣列
for(int i=1;i<n;i++)
{
int key=s[i],j=i-1;//將要其中一個數字拉出來 向左和每個位置的數字做比較
while(s[j]>key&&j>=0)//當前一個數字大於key時執行 但比較時不能超出自己的陣列
{
s[j+1]=s[j];//不能用到i j和j+1位置數字對調 j+1=i
j--;//j再往左移動一格作比較
}
s[j+1]=key;//
}
for(int i=0;i<n;i++)
cout<<s[i]<< " ";//輸出陣列
cout<<endl;
}
return 0;
}
```
7. ### ★ d452 二、直線最小距離和
:::info
- 排序後求中位數,中位數與數組各數的距離和最小
- swap()
- 其它排序演算法實作
* [exchange sort](http://it-easy.tw/sorting-algorithm/)
* [selection sort1](https://openhome.cc/Gossip/AlgorithmGossip/SelectionInsertionBubble.htm)
* [selection sort2](https://kopu.chat/2017/06/20/選擇排序-selection-sort/)
:::
```c==
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t,n;
cin>>t;
while(t--)//測試筆數
{
cin>>n;
int s[n],sum=0; //設置一個陣列
for(int i=0;i<n;i++)
cin>>s[i];//將數字讀入陣列
for(int i=1;i<n-1;i++)//因為要向右比較 所以最後一個不能向右比
{
int minIdx=i;//假設第一個位置的數字是最小值 這裡讀取的是位置
for(int j=i+1;j<n;j++)
{
if(s[j]<s[minIdx])//右邊的數字小於預設最小值
minIdx=j;//最小值換成右邊的數字
}
swap(s[minIdx],s[i]);//翻轉數字 最小值要到陣列的第一個位置所以s[minIdx]和s[0]互換
}
for(int i=0;i<n;i++)
sum+=abs(s[n/2]-s[i]);//距離絕對值
cout<<sum<< endl;
}
return 0;
}
```
8. ### ★ d153 六、智力测验
:::info
- 時間複雜度O(n^2^)的排序法會TLE
- (n-1)+(n-2)+….+1=n(n-1)/2=n2/2-n/2,當n很大時,如1百萬時,500,000,000,000-500,000=499,999,500,000(n/2可以忽略)
- 其它排序演算法觀念
* [merge sort](http://alrightchiu.github.io/SecondRound/comparison-sort-merge-sorthe-bing-pai-xu-fa.html)
* [quick sort1](http://notepad.yehyeh.net/Content/Algorithm/Sort/Quick/Quick.php)
* [quick sort2](https://ithelp.ithome.com.tw/articles/10202330?sc=iThelpR)
- 排序演算法比較
* [Sorting Algorithms Animations](https://www.toptal.com/developers/sorting-algorithms)
* [Comparison Sorting Algorithms](https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html)
:::
```c=
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n,t;
cin>>t;
while(t--)
{
cin>>n;
int s[n];
for (int i=0;i<n;i++)
cin >> s[i];//讀入陣列
sort(s,s+n);//不用演算過程的話可以用sort()
cout<<(n%2==1?s[n/2]:s[n/2-1])<<endl;//奇數可以直接取中數,偶數取兩數小的
}
return 0;
}
```
9. ### d478 共同的數 - 簡易版
:::info
- 依序比較兩數列
- C++ IO加速
``` javascript
ios::sync_with_stdio(false);
cin.tie(0);
```
:::
10. ### ★ a694 吞食天地二
:::info
- 二維陣列
:::
11. ### a015 矩陣的翻轉
:::info
- 二維陣列
:::
12. ### d596 1. 猜九宮格裡的地雷
:::info
- 因為只有9個格子,且每個格子只有4個相鄰格子,
所以以二維陣列記錄每個格子其相鄰格子的編號最簡單
- 以一維陣列記錄格子編號是否有地雷(bool)
- 「與地雷相鄰格子」的4個鄰居都可能是地雷
- 「與地雷不相鄰格子」的4個鄰居都不是地雷
:::
### 作業
1. ### b138: NOIP2005 1.陶陶摘苹果
2. ### b127: 會議中心(Room)
:::info
費式數列
:::
3. ### a034: 二進位制轉換
:::info
- 餘數輸出由下而上倒序寫 for(int j=i-1;j>=0;j\-\-)
:::
4. ### d097: 10038 - Jolly Jumpers
- 宣告一個記錄差的陣列d(初值為0),若兩數的差為3,則d[3]=1
- 輸入結束後,如果d[1~n-1]有0,則不是jolly jumper
5. ### d563: 等值首尾和
:::info
- 以迴圈讓prefix由前往後加,suffix由後往前加
- 如果prefix(前段和)==suffix(後段和)則答案加1,同時往前、後各加一個元素
- 如果prefix<suffix,則prefix往後加一個元素
- 如果prefix>suffix,則suffix往前加一個元素
:::
6. ### a040: 阿姆斯壯數
:::info
- pow(x,y)計算xy,需含入 cmath 標頭檔
- 以迴圈和%求n位數整數的個位、十位…,放入陣列,並計算n
- 再以迴圈將所有位數的n次方加起來,判斷是否等於此整數
:::
7. ### d123: 11063 - B2-Sequence
:::info
- 宣告一個記錄兩數和是否存在的陣列s(初值為0)
- 以兩數和當成index,如果不存在,則s[兩數和]=1
:::
8. ### d424: 00105 - The Skyline Problem
:::info
- 使用陣列紀錄每個x軸座標上的最高高度
- 輸出時注意邊界
:::
9. ### c435: MAX ! MAX ! MAX !
:::info
- 爆力解會TLE
- 往後掃描時不斷記錄最大範圍答案和最大值(一層迴圈完成)
:::
10. ### d481: 矩陣乘法
:::info
- 二維陣列
:::
11. ### a417: 螺旋矩陣
:::info
- 二維陣列
- memset將陣列歸零,memset(a,0,sizeof(a)); 需含入 cstring 標頭檔
- 逆時針即順時針的轉置矩陣
:::
12. ### b965: 第 2 題 矩陣轉換
:::info - 二維陣列
- 旋轉座標轉換

A (0,0) -> (0,2)
B (1,0) -> (0,1)
C (2,0) -> (0,0)
D (0,1) -> (1,2)
E (1,1) -> (1,1)
F (2,1) -> (1,0)
- 旋轉後的r,等於轉換前的c。
- 旋轉後的c,等於r數量(3)-r-1。
:::
13. ### a291: nAnB problem
:::info
- 使用陣列紀錄是否比較過
- 使用 scanf 和 printf 才不會TLE
:::
<br/>
## 五、CH5 字元陣列、字串
1. ### ★ a149: 乘乘樂
:::info
- 改寫為以字元陣列方式讀入
- 字串結束符號 '\0'
:::
```c=
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int product=1;
char n[11];
cin >> n;
for (int i=0;i<strlen(n);i++)
product*=(int)n[i]-48;
cout << product << endl;
}
return 0;
}
```
2. ### a009: 解碼器
3. ### ★ d124: 3的倍数
:::info
- 3的倍數判別法:各個數字和為3的倍數
:::
4. ### a054: 電話客服中心
:::info
- 注意100000000答案為KLY
:::
[演算法筆記-字串](https://archive.is/u1lQL)
5. ### ★ a782: 4. Redundant Acronym Syndrome Syndrome
:::info
- 不能使用cin >> s
- cin.getline(s,1000)
- toupper()將字元變大寫
- strcmp()比較兩字串是否相等
- 陣列的名字代表陣列開始的位址,s=="END"的寫法,即使s為"END"也不會相等
:::
```c=
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
string line;
while(getline(cin,line)&& line!="END")//讀入字串,在line=END時停止
{
int last;
cout << (char)toupper(line[0]);//將第一個字母變成大寫,而且將scii code換成字母
for(int i=1;i<line.size();i++)//從第二個字母開始搜索
{
if(line[i]==' ')//如果搜尋到空白,將後面一格變成大寫
{
cout << (char)toupper(line[i+1]);
last=i+1;//紀錄大寫字母位置
}
}
cout << " ";
for(int i=last;i<line.size();i++)
cout <<line[i];//將最後一個大寫字母到結束印出來
cout << endl;
}
return 0;
}
```
6. ### ★ a011: 00494 - Kindergarten Counting Game
:::info
- 不能只算空的數量,字母的前一個是非字母即一個字
- 不能使用cin >> s
- cin.getline(s,1000)
- isalpha()
:::
7. ### d614: 簡易加法運算
:::info
- 讀入測試筆數T後,需以getline(cin,str)將T後的換行字元讀掉,或cin.ignore()
- 以cin.getline()或getline(cin,str),讀入一行
- isdigit()判斷字元是否為數字
- 如果是數字,減48(0的ascii)得到數值,加前一個數字*10
- 如果不是數字,答案加上目前已經造出來的數字。
:::
8. ### ★ a022: 迴文
:::info
- string類別
- getline(cin,str)
- str.length()
- i\-\-
- str.clear()
- 將字串反轉後比較是否相等
:::
9. ### c290: APCS 2017-0304-1秘密差
:::info - string類別
- str.length()
- abs()可求絕對值,需含入 cstdlib 標頭檔
:::
10. ### ★ a130: 12015 - Google is Feeling Lucky
:::info
- 找最大值
- struct
- printf(),需含入 cstdio 標頭檔
:::
```c=
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
struct rec//結構類似陣列 可以將不同屬性同時放在一起 還可以分開比較
{
string name;
int v;
}web[10];
//=struct rec web[10]
int t,cs=1;
cin>>t;
while(t--)//測試筆數
{
int maxx=-1;
for(int i=0;i<10;i++)
{
cin>>web[i].name>>web[i].v;//將屬性輸入結構
if(web[i].v>maxx)//判斷點擊數大小
maxx=web[i].v;//將最大值找出來
}
printf("Case #%d:\n",cs++);//測試筆數印出
for(int i=0;i<10;i++)
{
if(web[i].v==maxx)
cout<<web[i].name<<endl;//點擊數最多網址印出
}
}
return 0;
}
```
---
### 作業
1. ### b428: 凱薩加密
2. ### a065: 提款卡密碼
:::info
- abs()可求絕對值,需含入 cstdlib 標頭檔
:::
3. ### d235: Q10929:You can say 11
:::info
- 11的倍數判別法:奇數位數字和與偶數位數字和相差為11的倍數
:::
4. ### a224: 明明愛明明
:::info
- 統計每個字母出現的次數
- 迴文的條件為:只有一個字母出現的次數是奇數或全部都是偶數
- 每筆測資統計的陣列要歸零
- isalpha()判斷字元是否為英文字母
- toupper()將字元變大寫
:::
5. ### a865: 5. Greek Numerals
:::info
- 將26個字母對應的值儲存為陣列
- #、$、3為多的字母
:::
6. ### d275: 11586 - Train Tracks
:::info
- 只要M和F數量一樣且軌道一個以上即可
- cin.ignore()
:::
7. ### c459: 2. 自戀數
:::info
- 可將N以字元陣列讀入
- strlen(N)計算其長度
- 數字字元-'0'求其數值
- pow(a,b)計算a^b^,需含入 cmath 標頭檔
- 根據進位制求出數值大小及每位數字的d次方合,比較是否相等
:::
8. ### d103: NOIP 2008 1.ISBN号码
:::info
- 數字字元-'0'求得其數值
- 計算識別碼,如果等於最後一個數字,或餘10且最後一個字元為'X',則為正確
:::
9. ### d086: 態度之重要的證明
:::info
- toupper()將字元變大寫或tolower()將字元變小寫
- A的ASCII值為65,a的ASCII值為97
:::
10. ### a275: 字串變變變
:::info
- 使用陣列儲存兩字串各別字母出現的次數(以字母的ascii為陣列索引)
- 如果各別字母出現次數一樣,表示可經由調整順序後,讓兩字串一樣
:::
11. ### d267: 11577 - Letter Frequency
:::info
- cin.ignore()把數字後的換行字元讀掉
- isalpha()判斷字元是否為英文字母
- tolower()將字元變大寫
- 以字母的ascii為陣列索引記錄出現次數,迴圈找出頻率最高的次數,迴圈印出頻率最高的字母
:::
12. ### d671: 11716 - Digital Fortress
:::info
- cin.ignore()把數字後的換行字元讀掉
:::
13. ### c462: apcs 交錯字串 (Alternating Strings)
:::info
- 找出每一個連續大(小)寫片段的長度並將其記錄在陣列
:::
<br />
## 六、CH6 函式
1. ### ★ d171: 飛蛾撲火(二)
:::info
- 內建函式:pow、log10、floor
- logN^M^ = M*logN
:::
```c=
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n,m;
while ( cin >> n >> m) {
cout <<floor( log10(pow(n,m)) + 1 )<< endl;
}
return 0;
}
```
```c=
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n,m;
while ( cin >> n >> m) {
cout <<floor( m*(log10(n))+ 1 )<< endl;//logNM = M*logN 次方算開會超時 用數學定理處理
}
return 0;
}
```
2. ### ★ c039: 00100 - The 3n + 1 problem
:::info
- 自訂函式(先練習寫pow(n,m))
- 內建函式:swap、max、min
:::
```C==
#include <iostream>
#include <cmath>
using namespace std;
int cl(int n)
{
int cnt=1;
while(n!=1)
{
if(n%2==1)
n=n*3+1;
else
n/=2;
cnt++;
return cnt;
}
}
```
```c=
#include <iostream>
using namespace std;
int cl(int n)
{
int i=1;
while (n!=1)
{
if (n%2==1)
n=3*n+1;
else
n=n/2;
i++;
}
return i;
}
int main()
{
int a,b,c,d;
while(cin >> a >> b)
{
int ans=0;
c=a;
d=b;
if(a>b)
swap(a,b);
for(int i=a;i<=b;i++) // for(int i=min(a,b);i<=max(a,b);i++)
ans=max(ans,cl(i));
cout << c << " " << d << " " << ans <<endl;
}
return 0;
}
```
```c=
#include <iostream>
using namespace std;
int cl(int n)//將重複的運算寫成函數庫
{
int i=1;
while (n!=1)
{
if (n%2==1)
n=3*n+1;
else
n=n/2;
i++;
}
return i;
}
int main()
{
int a,b;
while(cin >> a >> b)
{
int ans=0;
for(int i=min(a,b);i<=max(a,b);i++) // 將起點和終點先經過比較確定
ans=max(ans,cl(i));
cout << a << " " << a << " " << ans <<endl;
}
return 0;
}
```
3. ### ★ c294: APCS-2016-1029-1三角形辨別
:::info
- 自定交換函式swap(傳參考呼叫)(除錯Step into)
- 使用swap讓a,b,c依小->大排序(c為最長邊)
:::
4. ### a121: 質數又來囉
:::info
- 1不是質數
:::
5. ### ★ b112: 5.高中運動會
:::info
- 多個數的最大公因數
:::
6. ### ★ a216: 數數愛明明
:::info
- 遞迴(先印出費式數列)
- long long int
- TLE(遞迴求一般項)
:::
7. ### ★ a227: 三龍杯 -> 河內之塔
:::info
- 遞迴
- scanf()、printf() 需含入 cstdio 標頭檔
- [河內塔|樂和遊戲](http://www.novelgames.com/zh-HK/tower/)
- [河內塔程式參考](http://notepad.yehyeh.net/Content/DS/CH02/4.php)
:::
8. ### d269: 11579 - Triangle Trouble
:::info
- 排序後找連續3個邊,可構成最大三角形
- [更快的排序演算法 quick sort1](https://kopu.chat/2017/08/03/快速排序-quick-sort/)
- [quick sort2](http://www.algolist.net/Algorithms/Sorting/Quicksort)
:::
---
### 作業
1. ### d658: 11636 - Hello World!
:::info
- 以log2()求N為2的幾次方
- 以ceil()無條件進位
:::
2. ### d237: 質數合
:::info
- 以質數函式測試是否需加此數
- 不可直接輸出142913828922
:::
3. ### d117: 10924 - Prime Words
:::info
- 以質數函式測試字母值總合
:::
4. ### a623: Combination
:::info
- 將n!寫成函式,在主程式呼叫3次
:::
5. ### c002: 10696 - f91
:::info
- 遞迴
:::
6. ### d255: 11417 - GCD
:::info
- 將gcd寫成函式
:::
7. ### d693: 最小公倍數
:::info
- n個數的公倍數可以從兩兩連續求公倍數得到
- long long int
- 以遞迴求gcd
:::
8. ### c813: 11332 - Summing Digits
:::info
- 將f(x)寫成函式,不斷呼叫了式,直到n為個位數
:::
9. ### c015: 10018 - Reverse and Add
:::info
- 將數字反轉寫成函式
- 迴文的檢查為數字反轉後和原數字相等即是
:::
10. ### a263: 日期差幾天
:::info
- 判斷閏年可寫成函式
- 可算出總天數再相減
:::