考察抽象思维的一道题目,对各个方向进行编号,从w方向开始,将该方向编号为0,逆时针加1作为每个方向的编号,这样就可以保证对于编号i,1<<i也就满足对应方向的对应权值,然后从起始点开始,对于每个方向,判断这个方向是否存在障碍物,如果是存在障碍物的,那么就继续判断是否存在两个连续的障碍物,如果不是,那么就“移动”该障碍物,这个移动反映到数学上,也就是更新各个格子的数值,然后再递归判断,如果没有障碍物,就直接递归判断就行了,最后打印结果,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
int x, y;
int area[10][10];
const string dir = "WNES";
int dx[] = {0,-1,0,1};
int dy[] = {-1,0,1,0};
int getMinStep(int cur_x,int cur_y){
int res = 10;
for (int i = 1; i <= 4; i++){
if ((area[i][1] & 1) != 1){
res = min(res, abs(cur_x - i) + cur_y);
}
if ((area[i][6] & 4) != 4){
res = min(res, abs(cur_x - i) + 7 - cur_y);
}
}
for (int j = 1; j <= 6; j++){
if ((area[1][j] & 2) != 2){
res = min(res, abs(cur_y - j) + cur_x);
}
if ((area[4][j] & 8) != 8){
res = min(res, abs(cur_y - j) + 5 - cur_x);
}
}
return res;
}
bool dfs(int step,int cur_x,int cur_y,string s,int up1){
if (step == up1&&(cur_x == 0 || cur_x == 5 || cur_y == 0 || cur_y == 7)){
cout << s << endl;
return true;
}
int remain = getMinStep(cur_x, cur_y);
if (remain + step > up1) return false;
for (int i = 0; i < 4; i++){
int newx = cur_x + dx[i];
int newy = cur_y + dy[i];
if (newx >= 0 && newx <= 5 && newy >= 0 && newy <= 7){
if ((area[cur_x][cur_y] & (1 << i)) == (1 << i)){
if (newx != 0 && newx != 5 && newy != 0 && newy != 7 &&
(area[newx][newy] & (1 << i)) != (1 << i)){
area[cur_x][cur_y] -= (1 << i);
area[newx][newy] = area[newx][newy] - (1 << ((i + 2) % 4)) + (1 << i);
area[newx + dx[i]][newy + dy[i]] += (1 << ((i+2)%4));
if (dfs(step + 1, newx, newy, s + dir[i],up1)) return true;
area[cur_x][cur_y] += (1 << i);
area[newx][newy] = area[newx][newy] + (1 << ((i + 2) % 4)) - (1 << i);
area[newx + dx[i]][newy + dy[i]] -= (1 << ((i+2)%4));
}
}else{
if (dfs(step + 1, newx, newy, s+dir[i],up1)){
return true;
}
}
}
}
return false;
}
int main(){
while (cin >> y >> x){
if (x == 0 && y == 0) break;
for (int i = 1; i <= 4; i++){
for (int j = 1; j <= 6; j++){
cin >> area[i][j];
}
}
for (int up1 = 1;; up1++){
if (dfs(0, x, y, "",up1)){
break;
}
}
}
return 0;
}
这是一道考察抽象思维的编程题目。通过为每个方向分配编号,并利用位运算来表示方向的权值,可以解决遇到障碍物时的移动问题。算法从起点开始,检查每个方向,判断是否存在连续障碍物,若无则移动障碍物并递归检查,最终输出结果。详细实现见代码解析。
314

被折叠的 条评论
为什么被折叠?



