# S3 演算法 week 2
###### tags: `S3 公開資源`
:::info
時間:10/16 9:00 ~ 17:00
地點:成大資工系新館 **65304** 教室
主題:C++ 基礎語法(下)
直播連結:https://youtu.be/s3kvJUNUvVk
:::
## 課程內容
- 課程規則介紹
- C++ 語法基礎
- 迴圈
- 陣列
- 函式
- 講義連結:https://hackmd.io/@sa072686/cp/%2F%40sa072686%2FrJpY0i7PS
## 注意事項
1. 請先預習講義序章及初章前半第四章之後(含第四張)的內容,並且完成第一次上課的必做題
2. 第一堂課的必做題題解放在第一堂課的指引:https://hackmd.io/@SCIST/S1bifz-zo
3. 第一堂課請假或是未繳交同意書的實體學員,請務必繳回課前通知信所附的家長同意書
4. 上課期間請全程配戴口罩
5. 建議學員可以帶自己的筆電,以減少重新設定的時間成本
6. 請假表單:https://forms.gle/2ESVuTezcHCK959H6
# 必做題題解
[TOC]
## 初章 - 第四節
### [TOJ 578](https://toj.tfcis.org/oj/pro/578/)
撰寫者:Jun-an
從 0 開始跳 n 個格子,
但是只輸出奇數。
:::spoiler 參考程式碼 (while 迴圈版本)
```cpp=
#include <iostream>
using namespace std;
int main(){
int n, i;
cin >> n;
i = 0;
while(i < n){
if(i % 2 == 1){
cout << i << '\n';
}
i++;
}
return 0;
}
```
:::
:::spoiler 參考程式碼 (for迴圈版本)
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
for(int i = 1; i < n; i += 2){
cout << i << '\n';
}
return 0;
}
```
:::
---
### [TOJ 576](https://toj.tfcis.org/oj/pro/576/)
撰寫者:Eason
把數字一直除以10,直到他被除到0
然後用一個變數紀錄你總共除了幾次
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int counter = 0;//用這個變數紀錄總共除了幾次
while(n != 0){
counter++;
n /= 10;
}
cout << counter << '\n';
return 0;
}
```
:::
---
### [TOJ 577](https://toj.tfcis.org/oj/pro/577/)
撰寫者:Jun-an
本題須注意測資範圍!!!
有 $n$ 筆輸入,每筆皆要計算 $a ^ b$,
以 $2 ^ 3$ 為例,$2 ^ 3$ = $2$ * $2$ * $2$,
但其實可以改成 $2 ^ 3$ = $1$ * $2$ * $2$ * $2$,
因為 $a ^ 0$ = $1$,所以將答案預設為 $1$ 正好可以應對。
另外補充:
$pow(a, b)$ 雖然可以計算 $a ^ b$,但是回傳值是浮點數型別,
如果你要計算的 $a ^ b$ 是 $int$ 型別,很可能會出現誤差,
所以這裡不建議使用,請使用本堂課教的 $for / while$ 迴圈實作。
:::spoiler 參考程式碼
```cpp=
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
while(n--){
long long a, b, ans = 1;
cin >> a >> b;
for(int i = 0; i < b; ++i){
ans *= a;
}
cout << ans << '\n';
}
return 0;
}
```
:::
---
### [kattis FizzBuzz](https://open.kattis.com/problems/fizzbuzz)
撰寫者:Eason
給你三個數字X 、Y 還有N
要你輸出1 到N 中
可以被X 整除就輸出Fizz
可以被Y 整除就輸出Buzz
同時可以被X 跟Y 整除就輸出FizzBuzz
都不能被兩者整除就輸出當前數字
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
int x, y, n;
cin >> x >> y >> n;
for(int i=1; i<=n; i++){
if(i%x == 0 && i%y == 0){
cout << "FizzBuzz\n";
}
else if(i%x == 0){
cout << "Fizz\n";
}
else if(i%y == 0){
cout << "Buzz\n";
}
else{
cout << i << '\n';
}
}
return 0;
}
```
:::
---
### [kattis Job Expenses](https://open.kattis.com/problems/jobexpenses)
撰寫者:fishhh
給你一堆數字,把所有小於0的數加起來,就是答案ㄌ
:::spoiler 參考程式碼
```cpp
#include "iostream"
using namespace std;
int main(){
int n,k,ans=0; // 記得初始化
cin>>n;
for(int i=0;i<n;i++){
cin>>k;
if(k<0){
ans+=(k*-1);
}
}
cout<<ans;
}
```
:::
---
### [Atcoder abc204_b](https://atcoder.jp/contests/abc204/tasks/abc204_b)
撰寫者:Eason
把大於等於10 的數字減掉10 之後
全部加起來
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int temp, sum = 0;//記得要把sum 初始化為0
for(int i=0; i<n; i++){
cin >> temp;
if(temp >= 10){
sum += temp - 10;
}
}
cout << sum << '\n';
return 0;
}
```
:::
---
### [kattis Last Factorial Digit](https://open.kattis.com/problems/lastfactorialdigit)
撰寫者:fishhh
用迴圈將n!算出來,再取(n! % 10) 就可以知道n!的個位數是多少了
:::spoiler
```cpp=
#include "iostream"
using namespace std;
int main(){
int t,n;
cin>>t;
for(int i=0;i<t;i++){
cin>>n;
int tot=1;
for(int x=1;x<=n;x++){ // 算出n!
tot*=x;
}
cout<<tot%10<<"\n";
}
}
```
:::
---
### [kattis hailstone](https://open.kattis.com/problems/hailstone)
撰寫者:Eason
其實題目講的很明白了
你現在有個數字n
- 如果n 是1 就不進行操作
- 如果n 是奇數 就讓n 變成 3n + 1
- 如果n 是偶數 就讓n 變成 n / 2
不過題目有特別要求要把過程的n 全部加起來
所以要開一個變數儲存加總
:warning: 雖然題目給的數字範圍不會超過 int
但如果給一個足夠大的奇數 例如 $2^{31}-1$ 之類的
只要乘以3 就會馬上溢位
所以 即使題目給的數字在 int 以內 還是要小心!!
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
long long n, sum = 0;
cin >> n;
while(n!=1){
sum += n;
if(n % 2 == 0){
n = n / 2;
}
else{
n = 3 * n + 1;
}
}
sum += 1;
cout << sum << '\n';
return 0;
}
```
這個迴圈看到1 就會跳出
導致sum 在迴圈裡面是算不到1 的
所以第16行的用意就是補上沒加到的那個1
:::
---
### [Kattis climbingworm](https://open.kattis.com/problems/climbingworm)
撰寫者:Jun-an
一條蟲要從 0 爬到 h,
但是每往上爬 a 就會 下滑 b,
不過如果往上爬 a 的時候到達 h 就要結束。
:::spoiler 補充觀念
這裡提供其他作法,還是請使用本堂課所教觀念去做~
可以知道 爬到終點前所做的最後一個動作一定是向上爬 a
那麼 剩下的每次爬行都會上升 $(a-b)$ 的高度
所以 我們用除法即可算出要爬幾天
但這個做法要注意的是減掉 a 後變成負數的情形
:::
:::spoiler 參考程式碼
```cpp=
#include <iostream>
using namespace std;
int main(){
int a, b, h;
cin >> a >> b >> h;
int now = 0, i = 0;
while(true){
now += a;
i++;
if(now >= h){
break;
}
now -= b;
}
cout << i << '\n';
return 0;
}
```
:::
---
### [kattis Stopwatch](https://open.kattis.com/problems/stopwatch)
撰寫者:fishhh
可以先去想 什麼情況會出現「still running 」
||當n是奇數的時候||
這時候,我們就可以直接輸出 「still running 」 然後return 0
再來可以知道,按第一下後,計時器就會開始
第二下時 計時器就會停止
所以可以推得 兩個兩個一組 之間的時間就是計時器有在計時的時間
:::spoiler
```cpp 參考程式碼
#include "iostream"
using namespace std;
int main(){
int n;
cin>>n;
if(n%2==1){
cout<<"still running\n";
return 0;
//這裡寫的是比較簡單的寫法 因為只有一筆測資
//如果是多重輸入的話 還是要將測資讀完喔~
}
int ans=0,a,b;
for(int i=0;i<(n/2);i++){ //這邊的n必定是偶數 所以不會有被捨去的狀況
cin>>a>>b;
ans+=b-a;
}
cout<<ans<<"\n";
}
```
:::
---
### [kattis Soda Slurper](https://open.kattis.com/problems/sodaslurper)
撰寫者:fishhh
這題有迴圈解以及數學解
迴圈當然就是一次一次換 換到不能再換就可以把迴圈停掉了~
:::spoiler 參考程式
```cpp
#include<iostream>
using namespace std;
int main(){
int a,b,c,h,tot=0,tmp;
cin>>a>>b>>c;
h=a+b;
while(h>=c){
tot+=h/c;
tmp=h/c;
h%=c;
h+=tmp;
}
cout<<tot<<"\n";
return 0;
}
```
:::
:::spoiler 數學解
在這裡 這種題目會有兩種狀況
先假設每換一次需要$a$個空瓶,可以換得$b$瓶飲料(本題 $b=1$ )
1. 允許借空瓶 (這題不行
兌換一次實際會減少$(a-b)$個瓶子
於是每$n$個空瓶可以兌換到 $\lfloor \frac{n}{a-b} \rfloor * b$
2. 不允許借空瓶
可以先發現一件事
$if(n<a)$ 那麼一次都沒辦法兌換 qwq
$if(n>=a)$ 那麼就一直換 直到剩餘的空瓶數小於$a$就要暫停
那 我們會先留$a$個空瓶 做為未來可以借來用
> 至於為什麼是$a$個 可以這樣想 如果我們需要借大於等於$a$個
> 那我們必定無法把它還完 畢竟一次只會換到$b$個 且$b$一定小於$a$
> 那不是就永遠沒辦法還了?
再來我們就可以根據允許借空瓶的公式帶入
$n-a$個空瓶總共可以兌換 $\lfloor \frac{(n-a)}{(a-b)} \rfloor$ 次
然後如果要借 就一定會還完 所以我們剩下的$a$瓶 可以再換一次
(剩下的那$a$個換來的$b$瓶必定不能在換一次owo)
所以兌換總次數為:
$\lfloor \frac{(n-a)}{(a-b)} \rfloor + 1$ 次
化簡一下 就會變成
$\lfloor \frac{(n-b)}{(a-b)} \rfloor$ 次
最後 把次數乘上$b$就知道可以換到幾瓶惹~
$\lfloor \frac{(n-b)}{(a-b)} \rfloor *b$瓶
上式也就是這題的解
:::
## 間章
### [UVa 10963](http://domen111.github.io/UVa-Easy-Viewer/?10963)
簡單來說 就是判斷每一格的高度差是否相同即可~
(但題目好像有點難以理解?XD
:::spoiler
```cpp=
#include<iostream>
using namespace std;
int main(){
int n, W;
int y1, y2, dis;
bool ok;
while(cin>>n){
for( int i = 0 ; i < n ; i++ ){
if( i != 0)cout<<"\n";
cin>>W;
ok = true;
if( W != 0 ){
cin>>y1>>y2;
dis = y1-y2;
for( int j = 1 ; j < W ; j++ ){
cin>>y1>>y2;
if( y1-y2 != dis ) ok = false;
}
}
if( ok ) cout<<"yes\n";
else cout<<"no\n";
}
}
return 0;
}
```
:::
## 初章 - 第四節半
### [TOJ 104](https://toj.tfcis.org/oj/pro/104/)
撰寫者:Eason
這題找到規律 就很簡單了
當你在第i 層
那麼你的星星數量就是||2i - 1||
印出來會長這樣
> \*
> \***
> \*****
> \*******
所以只有找到這個規律是不夠的
我們還需要知道星星的前面有幾個空格
不難發現 就是||n - i||
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
for (space=n-1, star=1; space>=0; space--, star+=2) //建議將參數都寫在一起 迴圈內才不會很亂~
//也比較不需要去思考參數間的關係
{
for (i=0; i<space; i++)
{
cout << " ";
}
for (i=0; i<star; i++)
{
cout << "*";
}
cout << "\n";
}
return 0;
}
```
:::
---
### [Kattis sifferprodukt](https://open.kattis.com/problems/sifferprodukt)
撰寫者:fishhh
題意:
把一個數字 $x$ 每一位非零的數相乘,直到 $x$ 小於10(不能再繼續操作)
解法:
用while迴圈重複進行操作 直到 $x<10$
再用一個while迴圈取出 $x$ 的每個位數並相乘
:::spoiler 參考程式碼
```cpp=
#include "iostream"
using namespace std;
int main()
{
int x;
cin>>x;
while(x>=10){
int new_x=1;
while(x!=0){
int now=x%10;
if(now!=0){
new_x*=now;
}
x/=10;
}
x=new_x;
}
cout<<x<<"\n";
}
```
:::
---
### [Uva 488](http://domen111.github.io/UVa-Easy-Viewer/?488)
撰寫者:fishhh
實作題,用for迴圈會比較好完成
需要稍微注意一下換行符號的輸出~
:::warning
注意換行的問題 否則會拿到 PE
:::
:::spoiler 參考程式碼
```cpp=
#include "iostream"
using namespace std;
int main()
{
int n;
cin>>n;
int a,f;
for(int i=0;i<n;i++)
{
if(i!=0){
cout<<"\n";
}
cin>>a>>f;
for(int j=0;j<f;j++){
if(j!=0){
cout<<"\n";
}
for(int k=1;k<=a;k++){
for(int l=0;l<k;l++){
cout<<k;
}
cout<<'\n';
}
for(int k=a-1;k>=1;k--){
for(int l=0;l<k;l++){
cout<<k;
}
cout<<'\n';
}
}
}
}
```
:::
---
### [Math Homework](https://open.kattis.com/problems/mathhomework)
撰寫者:小麥
用for裡面在包for,要包三層,有一點要注意的是,每一層都要判斷計算是否已超過,如果有一組都沒有輸出的話則要輸出impossible
:::info
值得注意的是 再最後一圈 k 的時候 可以判斷 (n-i-j)%k==0 就好
也就是判斷 剩餘的腳數是否可以被k整除
可以省掉一些時間~
:::
:::spoiler 參考程式碼
```cpp
#include <iostream>
using namespace std;
int main() {
int a, b, c, n;
cin >> a >> b >> c >> n;
bool flag = true;
for (i=0; i<=n; i+=a)
{
for (j=0; i+j<=n; j+=b)
{
for (k=0; i+j+k<=n; k+=c)
{
if(i+j+k==n){
flag = false;
cout<<i<<" "<<j<<" "<<k<<"\n";
}
}
}
}
if (flag) {
cout << "impossible" << "\n";
}
return 0;
}
```
:::
---
### [TOJ 494](https://toj.tfcis.org/oj/pro/494/)
撰寫者:fishhh
用多層迴圈來完成這題(:warning:請自己練習:warning:)
:::spoiler 補充作法 by 小白
```cpp=
#include<iostream>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
for(int i = 1; i <= n; i++){ // 需要輸出的地板塊行數
for(int q = 1; q <= k; q++){ // 每個地板塊的高度(行數)
for(int j = 1; j <= n; j++){ // 每行有幾個地板塊
for(int p = 1; p <= k; p++){ // 每個地板塊的寬度
// if((i + j) % 2 == 0)
// cout << "*";
// else
// cout << ' ';
if(i%2 == 1){ // 奇數行
if(j%2 == 1){ // 奇數行的奇數塊先輸出星號,後輸出空白
cout << "*";
}
else{
cout << " ";
}
}
else if(i%2 == 0){ // 偶數行
if(j%2 == 1){ // 偶數行的偶數塊先輸出空白,後輸出星號
cout << " ";
}
else{
cout << "*";
}
}
}
}
cout << endl;
}
}
return 0;
}
```
:::
:::spoiler 作法 1(講師補充 非常簡潔 但需要一些觀察)
考慮同一橫排位置每+1輸出會變,所以看位置奇偶交替
考慮同一直排位置每+1輸出會變,所以同一直排上,看橫排位置奇偶交替
可得結論:直排橫排相加後的奇偶可決定要輸出的文字
(截自學員的code)

:::
:::spoiler 作法 2(比較好想? 但需要寫很多程式以及判斷)
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++){ //每行
for(int j=0;j<k;j++){
if(i%2==0){//奇數行
for(int l=0;l<n;l++){ //這裡 n 要減 1
if(l%2==0){
for(int g=0;g<k;g++){
cout<<"*";
}
}
else{
for(int g=0;g<k;g++){
cout<<" ";
}
}
}
}
else{
for(int l=0;l<n;l++){
if(l%2==0){
for(int g=0;g<k;g++){
cout<<" ";
}
}
else{
for(int g=0;g<k;g++){
cout<<"*";
}
}
}
}
cout<<"\n";
}
}
}
```
:::
---
## 初章 - 第五節
### [No Judge 儲存複數資料](https://hackmd.io/YTiYMA8zT9uCObxzri_11Q#%E5%84%B2%E5%AD%98%E8%A4%87%E6%95%B8%E8%B3%87%E6%96%99)
撰寫者:fishhh
用for迴圈加上陣列來完成
:::spoiler 參考程式碼
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,a[10];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
cout<<"a["<<i<<"] = "<<a[i]<<"\n";
}
}
```
:::
---
### [Reverse](https://open.kattis.com/problems/ofugsnuid)
撰寫者:小麥
先把資料存到陣列在倒放,記得陣列是從0開始數。
:::spoiler 參考程式碼
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int arr[100010];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
for (int i = n - 1; i >= 0; i--) {
cout << arr[i] << "\n";
}
return 0;
}
```
:::
---
### [License to Launch](https://open.kattis.com/problems/licensetolaunch)
撰寫者:小麥
找第一個最小值,並用一個變數存起來,為了方便可以將初使比較值設為一個大數。
:::spoiler 參考程式碼
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int arr[100010];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int mini = 99999999;
int ans;
for (int i = 0; i < n; i++) {
if (mini > arr[i]) {
ans = i;
mini = arr[i];
}
}
cout << ans << "\n";
return 0;
}
```
:::
---
### [Jumbo Javelin](https://open.kattis.com/problems/jumbojavelin)
撰寫者:小麥
請以練習陣列為主!
:::spoiler 作法1 (陣列解)
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,ary[120]={};
cin>>n;
for(int i=0;i<n;i++){
cin>>ary[i];
}
int tot=0;
for(int i=0;i<n;i++){
tot+=ary[i];
}
cout<<tot<<"\n";
}
```
:::
:::spoiler 作法2 (no 陣列)
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sum = 0;
for (int i = 0; i < n; i++) {
int in;
cin >> in;
sum += in;
}
cout << (sum - (n - 1)) << "\n";
return 0;
}
```
:::
---
### [No Judge 月份天數](https://hackmd.io/3bswkP4FRa-kE2S2ua7fcA#%E6%9C%88%E4%BB%BD%E5%A4%A9%E6%95%B8)
撰寫者:fishhh
:::spoiler
```cpp=
#include "iostream"
using namespace std;
int main(){
int day[]={31,28,31,30,31,30,31,31,30,31,30,31};
int n;
cin>>n;
cout<<day[n+1]<<"\n";
}
```
:::
---
### [No Judge 查詢出現次數](https://hackmd.io/p9Y-PTzWRZyqknDq3oPeGQ#%E6%9F%A5%E8%A9%A2%E5%87%BA%E7%8F%BE%E6%AC%A1%E6%95%B8)
撰寫者:小麥
先用陣列先把所有的值存起來,在去計算出現的次數。(再!!!)
---
### [最大出現次數 I](https://hackmd.io/p9Y-PTzWRZyqknDq3oPeGQ#%E6%9C%80%E5%A4%A7%E5%87%BA%E7%8F%BE%E6%AC%A1%E6%95%B8)
撰寫者:小麥
先用陣列先把所有的值存起來,在去看最大值。
---
### [最大出現次數 II](https://hackmd.io/p9Y-PTzWRZyqknDq3oPeGQ#%E6%9C%80%E5%A4%A7%E5%87%BA%E7%8F%BE%E6%AC%A1%E6%95%B81)
撰寫者:fishhh
用一個陣列來記錄每個數字的出現次數
以陣列的index值代表數字 而陣列的值即為其出現次數
:::spoiler 參考程式碼
```cpp=
#include "iostream"
using namespace std;
int main(){
int time[1200]={};//記得初始化
int n,k;
cin>>n;
for(int i=0;i<n;i++){
cin>>k;
time[k]++;
}
int max_time=0;
for(int i=1;i<=1000;i++){
if(time[i]>max_time){
max_time=time[i];
}
}
bool sec=0;
cout<<"ans: [";
for(int i=1;i<=1000;i++){
if(time[i]==max_time){
if(sec==1){
cout<<", ";
}
cout<<i;
sec=1;
}
}
cout<<"]\n";
}
```
:::
---
### [四天王](https://hackmd.io/p9Y-PTzWRZyqknDq3oPeGQ#%E5%9B%9B%E5%A4%A9%E7%8E%8B)
撰寫者:小麥
先用陣列先把所有的值存起來,在去計數。
---
### [kattis reducedidnumbers](https://open.kattis.com/problems/reducedidnumbers)
撰寫者:Eason
找到一個整數m
使得所有的SIN 除以m 的餘數都不同
如果有很多整數都符合m
那就輸出最小的那個
可以直接窮舉m
:::spoiler 參考程式碼
```cpp=
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int sin[n];
for (int i = 0; i < n; i++){
cin >> sin[i];
}
bool is_diff; //紀錄除以m的餘數是否相同,若true則全部不同,若false全部相同
int m = 1;
while (true){
is_diff = true; // 先假設全部相同
int tmp[n]; // 紀錄除以m的餘數
for (int i = 0; i < n; i++){
tmp[i] = sin[i] % m;
for (int j = 0; j < i; j++){
if (tmp[j] == tmp[i]){ //一旦找到兩個餘數相同的
is_diff = false; //就把is_diff變false
break;
}
}
if (!is_diff){
break; //如果is_diff為false 就不用繼續找了,直接break
}
}
if (is_diff){
break; //如果is_diff為true 就表示找到了
}
m++;
}
cout << m << '\n';
return 0;
}
```
:::
---
### [Kattis - lostlineup](https://open.kattis.com/problems/lostlineup)
撰寫者:fishhh
這題的操作要反過來思考,距離作為陣列的編號,最後在全部讀取出來。
:::spoiler 參考程式碼
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,k,ary[120]={};
cin>>n;
ary[1]=1;
for(int i=2;i<=n;i++){
cin>>k;
ary[k+2]=i;
}
for(int i=1;i<=n;i++){
cout<<ary[i]<<" ";
}
}
```
:::
---
### [No Judge 對稱](https://hackmd.io/@sa072686/cp/%2FaCmrox62TyKBuGzqdZ0e6g#%E5%B0%8D%E7%A8%B1)
撰寫者:fishhh
這裡的寫法很像迴文判斷的寫法,可以注意一下~~~~~~~
以下兩個參考程式差別在於迴圈形式不同
:::spoiler 參考程式1
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,k,ary[2000]={};
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>ary[i];
}
bool yes=1;
for(int i=0,j=n-1;i<j;i++,j--){ //包夾
int dif=ary[i]-ary[j];
if(dif<0)dif=-dif;
if(k<dif){
yes=0;
break;
}
}
if(yes){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}
}
```
:::
:::spoiler 參考程式2
```cpp=
#include "iostream"
using namespace std;
int main(){
int n,k,ary[2000]={};
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>ary[i];
}
bool yes=1;
for(int i=0;i<n/2;i++){
int dif=ary[i]-ary[n-i-1];
if(dif<0)dif=-dif;
if(k<dif){
yes=0;
break;
}
}
if(yes==1){
cout<<"YES\n";
}
else{
cout<<"NO\n";
}
}
```
:::