第一題:彗星撞擊 (題目敘述)
- 考點:二維陣列模擬 (區域改值 & 邊界判斷)
- 題解
- 主要是偵測以(a, b)為中心, 半徑為 s 上是否有恐龍, 如果沒有就每個點都扣掉 d
- 創一個陣列紀錄每一個點上有幾隻恐龍
- 遍歷影響範圍時,可以發現左界會是 b - s/2,上界是 a - s/2,因此可以左上角(a - s/2, b - s/2)去遍歷 s * s 的矩陣(記得要判斷邊界)
- 如果有恐龍(dino[i][j] > 0) , 先將清醒的恐龍數量減去 dino[i][j] 然後將 dino[i][j] 的值改成 0 ,否則全部減 d
#include<bits/stdc++.h>
using namespace std;
int main(){
int R=0,C=0,D=0,K=0,M=0;
cin >> R >> C >> D;
vector<vector<int>>mp (R,vector<int>(C,D));
vector<vector<int>>aw (R,vector<int>(C));
cin >> K;
for(int i=0;i<K;i++){
int a=0,b=0;
cin >> a >> b;
aw[a][b]++;
}
cin >> M;
for(int i=0;i<M;i++){
int a=0,b=0,s=0,d=0;
cin >> a >> b >> s >> d;
int r1 = max(0, a - s/2);
int r2 = min(R-1, a + s/2);
int c1 = max(0, b - s/2);
int c2 = min(C-1, b + s/2);
bool hasDino = false;
for(int x=r1;x<=r2;x++){
for(int y=c1;y<=c2;y++){
if(aw[x][y] != 0) hasDino = true;
}
}
if(hasDino){
for(int x = r1; x <= r2; x++)
for(int y = c1; y <= c2; y++)
aw[x][y] = 0;
}else{
for(int x = r1; x <= r2; x++)
for(int y = c1; y <= c2; y++)
mp[x][y] -= d;
}
}
int maxVal = mp[0][0];
int minVal = mp[0][0];
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
maxVal = max(maxVal, mp[i][j]);
minVal = min(minVal, mp[i][j]);
}
}
int total = 0;
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
total += aw[i][j];
}
}
cout << maxVal << " " << minVal << " " << total;
}第二題:航空拍照圖 (題目敘述)
- 考點:二維陣列模擬 (陣列旋轉)
- 題解
- 如果 r = c,翻轉的邊長都一樣,4個方向都要轉,反之 r != c,只要轉 0 度和 180 度,因為其他兩個轉出來的邊常會和原本的不符合
- 只要會翻轉陣列理論上這題就能寫出來 (另b為原本陣列)
- 向右翻轉 0 度, 即為 b 陣列
- 向右翻轉 90 度,arr[j][r-i-1] = b[i][j]
- (剩下的我用做幾次翻轉 90 度去跑)
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> rotate90(vector<vector<int>> mp){
int R = mp.size();
int C = mp[0].size();
vector<vector<int>> res(C, vector<int>(R));
for(int i = 0; i < R; i++){
for(int j = 0; j < C; j++){
res[j][R - 1 - i] = mp[i][j];
}
}
return res;
}
int compare(vector<vector<int>>& A, vector<vector<int>>& B){
int R = A.size();
int C = A[0].size();
int cnt = 0;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(A[i][j] == B[i][j]) cnt++;
}
}
return cnt;
}
int main(){
int R, C;
cin >> R >> C;
vector<vector<int>> A(R, vector<int>(C));
vector<vector<int>> B(R, vector<int>(C));
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
cin >> A[i][j];
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
cin >> B[i][j];
int total = R * C;
int best = 0;
for(int i=0;i<4;i++){
if(B.size() == A.size() && B[0].size() == A[0].size()){
best = max(best, compare(A, B));
}
B = rotate90(B);
}
cout << (best * 100 / total) << "%\n";
}第三題:商品包裝地 (題目敘述)
- 考點:字串
- 題解
- 題目簡單來說就是判斷奇數位置的數字總和 + 3 * 奇數位置的數字總和是否為 10 的倍數
- 不需要去特判驗證碼 c ,因為他剛好在奇數位置,直接加進去就好
- 如果該條碼合法要將其儲存 & 統計前三碼出現次數,以下有兩種方法
- 抓前三碼用整數 int a = (s[0] - '0'), b = (s[1] - '0'), c = (s[2] - '0'),該數字是 a * 100 + b * 10 + c,將其存在 cnt 陣列,最後輸出要記得補 0 (Example 1)
- 直接以前三碼為 index ,會使用到 map
<string, int>mp
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
string key;
map<string,int> cnt;
for(int i=0;i<n;i++){
int so=0,se=0;
cin >> key;
for(int j=0;j<12;j++){
int v = key[j] - '0';
if(j % 2 == 0) so += v;
else se += v;
}
int x = (so + 3 * se) % 10;
int check = key[12] - '0';
if( (x + check) % 10 == 0 ){
cnt[key.substr(0,3)]++;
}
}
string ans;
int mx = 0;
for(auto &p : cnt){
if(p.second > mx){
mx = p.second;
ans = p.first;
}
}
cout << ans << " " << mx << "\n";
}