# 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]也就是上次轉彎結果與這次相同的直接跳過判斷
``` cpp=
#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](與a[0][5]距離皆小於5)
=1+2+3+...8=36
因36除10餘6=a[o][5](6)
所以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中方便迴圈跑完後印出此點
``` cpp=
#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;
}
}
```