UVa 225 Golygons 題解
阿新 • • 發佈:2018-01-22
難點 每天 targe spl 交流 wikipedia code rtx tps
難度:β
建議用時:40 min
關於這道題目的背景在維基百科上有。很神奇。
但是我們的這道題沒有那麽多考慮。上來直接東南西北狂搜一通就好了。
算法很簡單,直接上過程。
首先確定 “東”“南”“西”“北” 對應的英文字母 “e”“s”“w”“n”。
因為題目還說不能後退,所以要把後退的方向也處理出來。”東“對”西“ 等等。
因為出發點在(0,0),又可以往負的方向走,為了用數組存,我們給每個坐標加一個 buf = 105 的東西,保證坐標都非負。
1 blocks[x+buf][y+buf] = 1;
另外因為對一個方向最多只走 buf 個距離,因此在範圍外的障礙物就 pass 掉。
1 if(abs(x) > buf || abs(y) > buf) continue;
下面直接東南西北搜。
1 void dfs(int curDepth, int curX, int curY, int lastDir) { 2 if(curDepth == lastLenth) { 3 if(curX == startX && curY == startY) { 4 output(); 5 total++; 6 } 7 returnView Code; 8 } 9 10 if(is_time_to_go_back(curDepth, curX, curY)) return; 11 12 for(int dir = 0; dir <= 3; dir++) { 13 int newX = curX + dx[dir]*(curDepth+1); 14 int newY = curY + dy[dir]*(curDepth+1); 15 16 if(abs(newX) > buf || abs(newY) > buf) continue; 17 if(block_in_the_way(curX, curY, newX, newY)) continue; 18 if(dir + lastDir == 3 || dir == lastDir) continue; 19 if(vis[newX+buf][newY+buf]) continue; 20 21 vis[newX+buf][newY+buf] = 1; 22 path[curDepth] = dir; 23 dfs(curDepth+1, newX, newY, dir); 24 vis[newX+buf][newY+buf] = 0; 25 } 26 }
註意這裏的細節:
1 if(dir + lastDir == 3 || dir == lastDir) continue;
回頭看:
1 const char directions[] = {‘e‘, ‘n‘, ‘s‘, ‘w‘};
哦!好妙!判斷方向方便很多!小技巧。
作為一到剪枝題,這裏的重點就在剪枝函數 “is_time_to_go_back” 上。
先分析一下。要想在規定的步數走回原點,容易想到要限制不能走太遠。因為走的距離和是有限的。而這裏的距離是以曼哈頓距離為參考的。所以自然要在這方面剪枝。
1 bool is_time_to_go_back(int curDepth, int curX, int curY) { 2 int manhattan_dist = abs(curX) + abs(curY); 3 int remain_dist = S[lastLenth] - S[curDepth]; 4 if(remain_dist < manhattan_dist) return true; 5 return false; 6 }
這個 “S” 就是等差數列前 n 項和。計算出還可以走多少曼哈頓距離。
構造 “S” :
1 void init() { 2 S[0] = 0; 3 for(int i = 1; i <= 20; i++) S[i] = S[i-1] + i; 4 }
這題還需判斷有沒有障礙物,上 code :
bool block_in_the_way(int sx, int sy, int tx, int ty) { if(sx > tx) swap(sx, tx); if(sy > ty) swap(sy, ty); for(int x = sx; x <= tx; x++) { for(int y = sy; y <= ty; y++) { if(blocks[x+buf][y+buf]) return true; } } return false; }
大概想法就是枚舉路上的每一個點,判斷是不是障礙物。
註意要保證 x 和 y 的遞增。否則枚舉會出問題。
總體過程結束了。
這題回頭看沒有什麽難點,曼哈頓距離就是求絕對值之和。不知道還有沒有更高效的剪枝方法。
不明白的請留言。
如果你對這篇文章感興趣,請關註我,我會定期(每天)更新文章。希望一起交流哈~
2018-01-22 00:02:04 (好晚啊)
UVa 225 Golygons 題解