6月apcs

有任何錯誤請多多指教
可以私我ig:eric_950922與我告知
也歡迎熱愛競程的可以來交個朋友?

第一題

難度:4/5(與考古題比較)
https://zerojudge.tw/ShowProblem?problemid=k731

想法

考試當下我看到時花了點時間在想,我認為此題是在歷年來中屬於較難的第一題,而這次與上次題目都是屬於座標題,建議新手可以拿起紙筆實際模擬一次會對於思考有很大的幫助!

步驟

在16行前皆是處理輸入處理
而實際處理題目我會分為兩個部分

一:
分別是18~35行的紀錄上次位置之方向
後來看到也有人用了16個 if (兩點定一個方向,兩個方向定一個轉彎)來暴力解
在我考試時思考一下後決定以a[]來儲存上一次的移動方向
並以右:0 下:1 左:2 上:3來存入vector
這樣可以在等等寫判斷式時省去不少時間

二:
37~85拿a[]的資料判斷左轉右轉與迴轉
這邊看不懂的人可以拿紙筆模擬一下就了解了
如果a[i]為0表示他前一步是朝右的(Y相同)
那就判斷a[i+1]和a[i]的大小關係來看是右轉或左轉,都不是的話就是迴轉
並且寫出 0 1 2 3 的判斷式(基本上都複製貼上只要改判斷x,y的地方)

hint

題目第二測資中會有題目中所說的可能不改變方向
那就要在第二部分判斷判斷式外包上if(a[i]!=a[i+1])
讓a[i]=a[i+1]也就是上次轉彎結果與這次相同的直接跳過判斷

#include<bits/stdc++.h> using namespace std; int main(){ int r=0,l=0,c=0; int n; cin>>n; vector<int>x; vector<int>y; vector<int>a; a.push_back(1); for(int i=0;i<n;++i){ int temp,temp2; cin>>temp>>temp2; x.push_back(temp); y.push_back(temp2); } for(int i=1;i<n+1;++i){ if(x[i]==x[i-1]){ if(y[i]>y[i-1]){ a.push_back(4); } else{ a.push_back(2); } } else if(y[i]==y[i-1]){ if(x[i]>x[i-1]){ a.push_back(1); } else{ a.push_back(3); } } } for(int i=0;i<n-1;++i){ if(a[i]!=a[i+1]){ if(a[i]==1){ if(a[i]==1&&y[i+1]>y[i]){ l++; } else if(a[i]==1&&y[i+1]<y[i]){ r++; } else{ c++; } } if(a[i]==2){ if(a[i]==2&&x[i+1]>x[i]){ l++; } else if(a[i]==2&&x[i+1]<x[i]){ r++; } else{ c++; } } if(a[i]==3){ if(a[i]==3&&y[i+1]>y[i]){ r++; } else if(a[i]==3&&y[i+1]<y[i]){ l++; } else{ c++; } } if(a[i]==4){ if(a[i]==4&&x[i+1]>x[i]){ r++; } else if(a[i]==4&&x[i+1]<x[i]){ l++; } else{ c++; } } } } cout<<l<<" "<<r<<" "<<c; }

第二題

難度:1/5(與考古題比較)
https://zerojudge.tw/ShowProblem?problemid=k732

想法

這題當下看到一樣需要花時間(慢慢)看懂題目
是屬於題目看起來難理解但做起來不複雜的矩陣題
後來寫完時覺得與考古題: 人口總和類似 https://zerojudge.tw/ShowProblem?problemid=f313
(一樣可以使用四層迴圈來在每個a[i][j]再對每個a[k][l]來進行操作)
但人口總和較困難(需考慮邊界問題和結束迴圈等等)

步驟

1~14行皆為輸入處理
而實際處理只有一個部分

一:
題目意思是對每個點a[i][j]進行判斷
從每個a[k][l]看是否有與自己距離<=a[i][j]者並把有的都加起來
(距離算法為|i-k|+|j-l|)
最後判斷如果此數除10之餘數等於其質(a[i][j])
此a[i][j]就定義為特殊位置
EX:測資一

1 8
1 2 3 4 5 6 7 8

輸入一個N*M矩陣
從a[i][j]開始判斷,而因為a[0][0]=1所以總合為a[o][0]+[0][1]=2
但2除10餘2不等於1(a[0][0])
當跑到a[0][5]時為5,總和為a[0][0]+a[0]7
=1+2+3+8=36
因36除10餘6=a[o]5
所以a[0][5]就為特殊位置
最後輸出有幾個特殊位置並分別輸出其x,y
16~18行分別對每個a[i][j]進行判斷
17行另一個總和並讓每個a[i][j]都重新歸零
18~24讓每個a[k][l]判斷與a[i][j]距離是否小於自己,有的話就加入總和
25~28判斷總和除10之餘數是否等於自己,是的話此a[i][j]就是特殊位置
並讓答案變數+1,另外把x,y都丟到vector中方便迴圈跑完後印出此點

#include<bits/stdc++.h> using namespace std; int main(){ int ans=0; int a[100][50]={}; int n,m; cin>>n>>m; vector<int>x; vector<int>y; for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ cin>>a[i][j]; } } for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ int sum=0; for(int k=0;k<n;++k){ for(int l=0;l<m;++l){ if(abs(i-k)+abs(j-l)<=a[i][j]){ sum+=a[k][l]; } } } if(sum%10==a[i][j]%10){ x.push_back(i); y.push_back(j); ans++; } } } cout<<ans<<endl;; for(int i=0;i<ans;++i){ cout<<x[i]<<" "; cout<<y[i]; cout<<endl; } }