您的位置:首页 > 其它

hdu1515 hdu1401 搜索

2010-08-02 20:41 92 查看
hdu1515

Anagrams by Stack

深搜能过,想好搜索技巧,很容易过。

题意:给你两个字符串,问:第一个字符串按入栈出栈规则,能否达到第二个字符串,输出所有的方法,i表示入栈,o表示出栈。

用dfs模拟第一个字符串入栈出栈过程:

1. 当前字符入栈,就向下一层递归,即搜向下一个字符

2. 栈顶元素出栈,对新的栈顶元素判断

这题要求按字典序输出,这种先判断入,再判断出的方法正好符合。

代码

#include<stdio.h>
#include<stdlib.h>
#include<set>
using namespace std;
int ok;
unsigned __int64 ans;
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
typedef struct node{
int x[5];
int y[5];
int n;
}NODE;

NODE sta, end, que[106540];
set<unsigned __int64> se;
int Judge(int x[], int y[], int nxtx, int nxty, int i){
int k;
for (k = 0; k < 4; k++){
if (k == i){
continue;
}
if (x[k] == nxtx && y[k] == nxty){
return 0;
}
}
return 1;
}

void putin(NODE a){
int i;
ans = 0;
for (i = 0; i < 4; i++){
ans += (unsigned __int64)1 << ((a.x[i] - 1) * 8 + a.y[i] - 1);
}
se.insert(ans);
}
void bfs1(){
NODE cur, nxt;
que[0] = sta;

int head, tail, i, j, t1, t2, k;
putin(sta);
head = tail = 0;
while(head <= tail){
cur = que[head++];
/*    for (k = 0; k < 4; k++){
printf("%d %d ", cur.x[k], cur.y[k]);
}*/
for (i = 0; i < 4; i++){

for (j = 0; j < 4; j++){
nxt = cur;
nxt.n = cur.n + 1;
if (nxt.n > 4) return;
nxt.x[j] = dir[i][0] + cur.x[j];
nxt.y[j] = dir[i][1] + cur.y[j];
if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8){
if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
t1 = se.size();
putin(nxt);
t2 = se.size();
if (t1 != t2){
que[++tail] = nxt;
}
}else{
nxt.x[j] = dir[i][0] + nxt.x[j];
nxt.y[j] = dir[i][1] + nxt.y[j];
if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8){
if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
t1 = se.size();
putin(nxt);
t2 = se.size();
if (t1 != t2){
que[++tail] = nxt;
}
}
}
}
}
}
}
}
}

void bfs2(){
NODE cur, nxt;
que[0] = end;

int head, tail, i, j, t1, t2;
t1 = se.size();
putin(end);
t2 = se.size();
if (t1 == t2){
ok = 1;
return;
}
se.erase(ans);
head = tail = 0;
while(head <= tail){
cur = que[head++];
for (i = 0; i < 4; i++){

for (j = 0; j < 4; j++){
nxt = cur;
nxt.n = cur.n + 1;if (nxt.n > 4) return;
nxt.x[j] = dir[i][0] + cur.x[j];
nxt.y[j] = dir[i][1] + cur.y[j];
if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8){
if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
que[++tail] = nxt;
t1 = se.size();
putin(nxt);
t2 = se.size();
if (t1 == t2){
ok = 1;
return;
}
se.erase(ans);
}else{
nxt.x[j] = dir[i][0] + nxt.x[j];
nxt.y[j] = dir[i][1] + nxt.y[j];
if (nxt.x[j] >= 1 && nxt.x[j] <= 8 && nxt.y[j] >= 1 && nxt.y[j] <= 8){
if (Judge(cur.x, cur.y, nxt.x[j], nxt.y[j], j)){
que[++tail] = nxt;
t1 = se.size();
putin(nxt);
t2 = se.size();
if (t1 == t2){
ok = 1;
return;
}
se.erase(ans);
}
}
}
}
}
}
}
}
int main()
{
int i;
while (scanf("%d%d", &sta.x[0], &sta.y[0]) != EOF){
for (i = 1; i <= 3; i++){
scanf("%d%d", &sta.x[i], &sta.y[i]);
}
sta.n = 0;
for (i = 0; i <= 3; i++){
scanf("%d%d", &end.x[i], &end.y[i]);
}
end.n = 0;
ok = 0;
bfs1();
bfs2();
if (ok) puts("YES");
else puts("NO");
se.clear();
}
return 0;
}


代码重复性很高,可以稍作处理,减少代码量。这里用set判重,如果set的大小没变,说明加入的值已存在。

加几组数据:

1 4 3 7 4 5 6 2 1 4 3 7 4 5 6 2

2 1 8 8 7 8 1 1 1 5 8 7 7 7 2 4

6 5 5 7 5 1 7 1 7 7 6 5 5 7 6 3

4 6 5 6 5 5 5 2 2 2 7 6 5 3 5 2

4 4 5 5 3 4 7 2 2 7 7 2 6 5 4 8

4 2 3 4 5 5 6 6 2 7 4 4 3 5 4 5

3 3 5 3 6 2 6 6 6 3 8 3 6 6 6 8

3 2 5 3 6 2 6 6 6 3 8 3 6 6 6 8

3 4 4 5 5 5 7 5 3 3 4 3 5 3 6 3

解为:

YES

YES

YES

YES

YES

YES

YES

NO

YES
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: