乙個有效的剪枝是排除等效冗沉,當兩種操作形成等效效果時不重複搜尋
若有兩個塊,那麼左邊的右移和右邊的左移是等效的,由於題意認為右移優先於左移,所以這種情況只取右移,而乙個塊左邊是空的時候則要嘗試左移
在回溯法「還原」的時候,可以先複製出來局面,在函式裡開陣列(別用全域性的,要儲存多個局面),然後複製回去
但仔細想想不需要再複製回去了,大不了每次都開個陣列,直接當dfs的引數傳下去,然後每次dfs用引數表裡的陣列就是了
因為一開始我沒想到那個「左右移等效」,為了不讓乙個塊來回左右走許多次,我記了個lasti 表示上一次移動的塊的座標,但是lasti初始值應為-1 因為 0,0 也是合法的座標,並且lasti應該在引數表裡而不是全域性定義
#include
#include
#include
#include
#include
using
namespace
std;
#define debug(x) cerr << #x << "=" << x << endl;
const
int maxn = 100;
int g[maxn][maxn], n, h[maxn], cg[10][10], fg[10][10],ans[10][10],sum[10];
bool *** = false, now_***;
void copy(int a[5][7])
void reco(int a[5][7])
void tran()
}void vert()
}void corr()
}memset(fg, 0, sizeof(fg));
}void modify(int x, int y, int mx) while(now_***);
}bool check()
void dfs(int x, int lasti, int lastj)
return;
}for(int i=0; i<5; i++)
for(int j=0; j<7; j++)
if(i != 0 && g[i-1][j] == 0)
}}int main() while(x != 0);
}dfs(1, -1, -1);
if(***)
for(int i=1; i<=n; i++)
printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]);
else
printf("-1");
return
0;}
NOIP2011 Mayan遊戲 搜尋
第一反應是搜尋題,想了一下如果用bfs的話,由於狀態過多,可能超記憶體,因此我用的dfs。這裡我們討論一下剪枝條件 如果當前狀態有一種顏色的數量小於3,那麼這種顏色就無法被消除,因此我們可以提前退出迭代。如果兩個連著的方塊顏色是相同的話,我們不用交換。如果兩個非空的方塊交換,我們只用考慮左邊那個方塊...
NOIP2011 Mayan遊戲 題解
mayan puzzle是最近流行起來的乙個遊戲。遊戲介面是乙個7行5列的棋盤,上面堆放著一些方塊,方塊不能懸空堆放,即方塊必須放在最下面一行,或者放在其他方塊之上。遊戲通關是指在規定的步數內消除所有的方塊,消除方塊的規則如下 1 每步移動可以且僅可以沿橫向 即向左或向右 拖動某一方塊一格 當拖動這...
noip2011 Mayan遊戲 dfs 模擬
能力太弱啊,調了一天。首先我bfs掛了,因為狀態太多而mle,好像只能dfs,然後bfs改dfs過程中傻x錯誤一大堆。這道題主要是模擬比較麻煩,消除塊的情況非常複雜。剪枝的話,如果乙個塊左邊有塊,就不用搜它向左移的情況,因為左邊的塊向右移會更優。剪這乙個應該就可以。還有總結這幾天做題經驗,一定謹慎使...