# 方法
跟窮舉超像,就是設法模擬出答案的狀況
跟窮舉差別就在 -> 狀況通常都比較複雜一點點,要再多考慮一下
# 例題
# c006: 10550 - Combination Lock
# 內容
你今天的任務需要來開一個鎖(如右圖)。在鎖上有一個轉盤,上面有 40 個刻度(0 到 39 來代表)。開鎖的密碼由 3 個號碼組成,例如:15-25-8。要打開這種鎖要按照以下步驟:
- 順時鐘方向轉轉盤 2 整圈
 - 繼續順時鐘方向轉直到到達第一個號碼上
 - 逆時鐘方向轉轉盤一整圈
 - 繼續逆時鐘方向轉直到到達第二個號碼
 - 順時鐘方向轉轉盤直到到達第三個號碼
 - 拉開鎖頭就可以打開了
給你一開始時轉盤的位置,還有開鎖的密碼,請你算出總共要轉多少度(degree,一整圈為 360 度)才能打開鎖(順時鐘方向加逆時鐘方向)。 
# 思路
記得一件事: 轉盤順時針轉的時候數字是減少的
先把轉幾圈整的加到答案裡
問題剩下從起點順時針轉到 A,逆時針轉到 B,順時針轉到 C
起點順時針轉到 A = ((s-(a-40))%40)*9
其中 9 是每一格的角度
逆時針到 B = ((b+40)-a)%40) * 9
# 程式碼
#include<iostream> | |
using namespace std;  | |
int main()  | |
{ | |
int s;  | |
int a,b,c;  | |
int ans;  | |
while(cin>>s>>a>>b>>c){  | |
if(s==0 && a==0 && b==0 && c==0)  | |
return 0;  | |
ans = 1080;  | |
ans += ((s-(a-40))%40) * 9;  | |
ans += (((b+40)-a)%40) * 9;  | |
ans += ((b-(c-40))%40) * 9;  | |
cout<<ans<<endl;  | |
        } | |
return 0;  | |
} | 
# c292: APCS2017-0304-3 數字龍捲風
# 內容
給定一個二維陣列,依照題目需要從中間逆時針或順時針向外 輸出答案
# 思路
就是很純的模擬
先從中間開始,把中間的那圈走完,再往外拓張,直到走完全圖
# 程式碼
#include <iostream> | |
using namespace std;  | |
int main(){  | |
int N, nxt;  | |
while (cin >> N) {  | |
cin >> nxt;  | |
int a[N][N];  | |
for (int i=0; i<N; i++){  | |
for (int j=0; j<N; j++){  | |
cin >> a[i][j];  | |
            } | |
        } | |
        // 0 代表左 、1 代表上 、2 代表右 、3 代表下 | |
int direction[4][2] = <!--swig0-->;  | |
int total_steps = N * N, steps = 1;  | |
int repeat = 1, repeat_cnt = 0;  | |
int r = N / 2, c = N / 2; // 從中心點出發  | |
cout << a[r][c];  | |
while (steps < total_steps){  | |
for (int i=0; i<repeat; i++){  | |
r += direction[nxt][0];  | |
c += direction[nxt][1];  | |
cout << a[r][c];  | |
steps++;  | |
if (steps == total_steps) break;  | |
            } | |
repeat_cnt++;  | |
if (repeat_cnt % 2 == 0){  | |
repeat++;  | |
            } | |
nxt = (nxt + 1) % 4;  | |
        } | |
cout << '\n';  | |
    } | |
return 0;  | |
} | 
# c297: APCS-2016-1029-4 棒球遊戲
# 題目
有點長,所以只放連結喔~
# 思路
安打時,除了原本在壘包上的人要移動外,還要加上一個從本壘走出來的人。例如 2B:原本在壘上的人往前跑 2 個壘,而本壘的人跑到 2 壘。
打出 2 壘安打時,可以想成每個人都往前進一格兩次
打出 3 壘安打時,可以想成每個人都往前進一格三次
全壘打時,跑 4 個壘就相當於原本壘上的所有人皆得分,還要外加本壘出來的人的分數。
在用 queue 模擬時,沒有人的地方可以假設為數字 0,有人的地方假設為數字 1(或其他數字)。
跑壘時讀到人(也就是數字 1)=> 得分
部分模擬的題目,也可以到很難喔~這可是 APCS 的第四題ㄟ
# 程式碼
#include <bits/stdc++.h> | |
using namespace std;  | |
map<int, queue<string> > mp;// 紀錄用,也可以用二維陣列代替  | |
int main(){  | |
int a, target;  | |
    string s; | |
for (int i=0; i<9; i++){  | |
cin >> a;  | |
queue <string> q;  | |
for (int j=0; j<a; j++){  | |
cin >> s;  | |
q.push(s);  | |
        } | |
mp[i] = q;  | |
    } | |
cin >> target;  | |
int out = 0, num = -1, score = 0;  | |
int b1 = 0, b2 = 0, b3 = 0, b4 = 0;  | |
while (1){  | |
int times = 0; // 跑壘數  | |
num = (num + 1) % 9; // 打者號碼  | |
string hit = mp[num].front();  | |
mp[num].pop();  | |
if (hit == "SO" || hit == "GO" || hit == "FO"){  | |
out += 1;  | |
if (out == target) break;  | |
if (out % 3 == 0){  | |
b1 = b2 = b3 = b4 = 0;  | |
            } | |
} else if (hit == "HR"){  | |
times = 4;  | |
} else {  | |
times = hit[0] - '0';  | |
        } | |
        // 跑壘 | |
for (int i=1; i<=times; i++){  | |
b4 = b3;  | |
b3 = b2;  | |
b2 = b1;  | |
if (i == 1) b1 = 1;  | |
else b1 = 0;  | |
if (b4 == 1) {  | |
score++;  | |
            } | |
        } | |
    } | |
cout << score << '\n';  | |
return 0;  | |
} |