검색 (8 번 문제 상세 설명: BFS, A *, IDA *) - Eight (POJ 1077)
71400 단어 ACM 알고리즘(문제 풀이):수색 하 다.
int fac[] = { 1,1,2,6,24,120,720,5040,40320 };// 。
int Cantor( int s[])// 。
{
int sum = 0;
for(int i = 0;i<9;i++)
{
int cnt = 0;
for(int j=i+1;j<9;j++)
{
if( s[i] > s[j] ) cnt++;
}
sum+=(cnt*fac[9-i-1]);
}
return sum+1;
}
#include
#include
#include
#include
#include
#include
//
using namespace std;
const int maxn = 1000000;
int fac[] = { 1,1,2,6,24,120,720,5040,40320 };
bool flag [maxn];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
string cmd = "udlr";
int aim=46234;
int Cantor( int s[])
{
int sum = 0;
for(int i = 0;i<9;i++)
{
int cnt = 0;
for(int j=i+1;j<9;j++)
{
if( s[i] > s[j] ) cnt++;
}
sum+=(cnt*fac[9-i-1]);
}
return sum+1;
}
struct node
{
int s[9];
int loc;
int status;
string path;
};
node origin;
string path;
int BFS()
{
queue q;
while ( !q.empty() )
q.pop();
node cur,temp;
q.push(origin);
int x,y;
while( !q.empty() )
{
cur = q.front();
q.pop();
if( cur.status == aim )
{
path = cur.path;
return 1;
}
x = cur.loc/3;
y = cur.loc%3;
for(int i=0;i<4;i++)
{
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if( tx<0 || ty <0 || tx>2 || ty>2 ) continue;
temp = cur;
temp.loc = tx*3 + ty;
temp.s[cur.loc] = temp.s[temp.loc];
temp.s[temp.loc] = 0;
temp.status = Cantor(temp.s);
if( !flag[temp.status] )
{
flag[temp.status] = 1;
temp.path = temp.path + cmd[i];
if( temp.status == aim )
{
path = temp.path;
return 1;
}
q.push(temp);
}
}
}
return 0;
}
int main()
{
char ch;
while(cin>>ch)
{
if(ch == 'x')
{
origin.s[0] = 0;
origin.loc = 0;
}
else origin.s[0] = ch - '0';
for(int i=1;i<9;i++)
{
cin >> ch;
if( ch == 'x' )
{
origin.s[i] = 0;
origin.loc = i;
}
else origin.s[i] = ch - '0';
}
origin.status = Cantor( origin.s );
memset( flag , 0 ,sizeof(flag) );
if(BFS())
cout<else
printf("unsolvable
");
}
return 0;
}
#include
#include
#include
#include
#define FUCK puts("fuck!")
#define STOP system("pause")
#define MAXN 388211
using namespace std;
struct state{
int sta,pos,step;
int visit;
}st[MAXN],source,target;
int temp[10],tar[10],sou[10];
int d[9][4]={{0,4,0,2},{0,5,1,3},{0,6,2,0},{1,7,0,5},{2,8,4,6},{3,9,5,0},{4,0,0,8},{5,0,7,9},{6,0,8,0}};
int num;
int convert(int a[],state &b)
{
b.sta=0;
for(int i = 0; i < 9; i ++)
{
if(a[i]!=0)
b.sta |=((a[i]-1)<24-i*3));
else
{
b.pos = i;
b.sta |=(a[i]<24-i*3));
}
}
return 1;
}
state exchange(state a,int pos)
{
int temp = 7<9-pos)*3);
state s;
s.sta = a.sta;
temp = temp & a.sta;
temp = ((temp>>((9-pos)*3))<9-a.pos-1)*3));
s.sta |= temp;
s.sta &= ~(7<9-pos)*3));
s.pos = pos-1;
return s;
}
int search(state a)
{
int index = a.sta%MAXN;
bool flag = true;
while(flag)
{
if(!st[index].sta)
{
st[index].sta = a.sta;
st[index].pos = a.pos;
flag = false;
}
else if(!(st[index].sta^a.sta)&&!(st[index].pos^a.pos))
flag = false;
else
index = (index+1)%MAXN;
}
return index;
}
int main()
{
freopen("in.txt","r",stdin);
clock_t start,end;
for(int j=0;j<8;j++)temp[j] = j+1;
temp[8]=0;
convert(temp,target);
while(1)
{
int i = 0;
memset(st,0,sizeof(st));
char ch;
while((ch=getchar())!='
')
{
if(ch<='9'&&ch>='0')
sou[i++] = ch - '0';
else if(ch=='x')
sou[i++] =0;
}
convert(sou,source);
start = clock();
i = search(source);
queue<int>q;
q.push(i);
i = search(target);
st[i].visit = 1;
st[i].step = 1;
q.push(i);
if(!(source.sta^target.sta)&&!(source.pos^target.pos))
{
printf("0
");
while(!q.empty())q.pop();
continue;
}
int index;
int count = 0;
bool isSolve = false;
while(!q.empty()&&!isSolve)
{
count ++;
index = q.front();
for(int j = 0; j < 4; j ++)
{
if(d[st[index].pos][j])
{
int flag = search(exchange(st[index],d[st[index].pos][j]));
if(!st[flag].step)
{
st[flag].step = st[index].step + 1;
st[flag].visit = st[index].visit;
q.push(flag);
}
else
{
if(st[flag].visit^st[index].visit)
{
isSolve = true;
printf("%d
",st[index].step+st[flag].step);
}
}
}
}
q.pop();
}
while(!q.empty())q.pop();
end = clock();
printf("Time:%dms
state number:%d
",end-start,count);
}
system("pause");
return 0;
}
#include
#include
#include
#include
#define FUCK puts("fuck!")
#define STOP system("pause")
#define MAXN 388211
using namespace std;
struct state{
int sta,pos,step;
int f;
}st[MAXN],source,target;
int temp[10],tar[10],sou[10];
int d[9][4]={{0,4,0,2},{0,5,1,3},{0,6,2,0},{1,7,0,5},{2,8,4,6},{3,9,5,0},{4,0,0,8},{5,0,7,9},{6,0,8,0}};
int num;
int h(state a)
{
int temp = target.sta;
int cnt=0;
for(int i = 0;i < 9; i ++)
{
if(a.pos==target.pos)
{
if(!(((temp>>(3*i))&7)^((a.sta>>(3*i))&7)))
cnt++;
}
else
{
if((!(((temp>>(3*i))&7)^((a.sta>>(3*i))&7)))&&((a.sta>>(3*i))&7))
cnt++;
}
}
return 9-cnt;
}
struct cmp
{
bool operator () (int u, int v)
{
return st[u].f > st[v].f;
}
};
int convert(int a[],state &b)
{
b.sta=0;
for(int i = 0; i < 9; i ++)
{
if(a[i]!=0)
b.sta |=((a[i]-1)<24-i*3));
else
{
b.pos = i;
b.sta |=(a[i]<24-i*3));
}
}
return 1;
}
state exchange(state a,int pos)
{
int temp = 7<9-pos)*3);
state s;
s.sta = a.sta;
temp = temp & a.sta;
temp = ((temp>>((9-pos)*3))<9-a.pos-1)*3));
s.sta |= temp;
s.sta &= ~(7<9-pos)*3));
s.pos = pos-1;
return s;
}
int search(state a)
{
int index = a.sta%MAXN;
bool flag = true;
while(flag)
{
if(!st[index].sta)
{
st[index].sta = a.sta;
st[index].pos = a.pos;
flag = false;
}
else if(!(st[index].sta^a.sta)&&!(st[index].pos^a.pos))
flag = false;
else
index = (index+1)%MAXN;
}
return index;
}
int main()
{
freopen("in.txt","r",stdin);
clock_t start,end;
for(int j=0;j<8;j++)temp[j] = j+1;
temp[8]=0;
convert(temp,target);
while(1)
{
int i = 0;
memset(st,0,sizeof(st));
char ch;
while((ch=getchar())!='
')
{
if(ch<='9'&&ch>='0')
sou[i++] = ch - '0';
else if(ch=='x')
sou[i++] =0;
}
convert(sou,source);
start = clock();
i = search(source);
st[i].f = h(st[i]);
priority_queue<int,vector<int>,cmp>q;
q.push(i);
int index;
int count = 0;
while(!q.empty())
{
count++;
index = q.top();
q.pop(); //!!!!
if(!(st[index].sta^target.sta)&&st[index].pos == target.pos)
{
printf("%d
",st[index].step);
break;
}
for(int j = 0; j < 4; j ++)
{
if(d[st[index].pos][j])
{
int flag = search(exchange(st[index],d[st[index].pos][j]));
if(!st[flag].step||st[flag].step > st[index].step + 1)
{
st[flag].step = st[index].step + 1;
st[flag].f = st[flag].step + h(st[flag]);
q.push(flag);
}
}
}
}
while(!q.empty())q.pop();
end = clock();
printf("Time:%dms
state number:%d
",end-start,count);
}
system("pause");
return 0;
}
manhattan 거리 함수 기반 A * 검색:
#include
#include
#include
#include
#define FUCK puts("fuck!")
#define STOP system("pause")
#define MAXN 388211
using namespace std;
struct state{
int sta,pos,step;
int f;
}st[MAXN],source,target;
int temp[10],tar[10],sou[10];
int d[9][4]={{0,4,0,2},{0,5,1,3},{0,6,2,0},{1,7,0,5},{2,8,4,6},{3,9,5,0},{4,0,0,8},{5,0,7,9},{6,0,8,0}};
int num;
int manhattan[10][10] = // i Manhattan
{
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1, 0, 1, 2, 1, 2, 3, 2, 3, 4},
{-1, 1, 0, 1, 2, 1, 2, 3, 2, 3},
{-1, 2, 1, 0, 3, 2, 1, 4, 3, 2},
{-1, 1, 2, 3, 0, 1, 2, 1, 2, 3},
{-1, 2, 1, 2, 1, 0, 1, 2, 1, 2},
{-1, 3, 2, 1, 2, 1, 0, 3, 2, 1},
{-1, 2, 3, 4, 1, 2, 3, 0, 1, 2},
{-1, 3, 2, 3, 2, 1, 2, 1, 0, 1},
{-1, 4, 3, 2, 3, 2, 1, 2, 1, 0}
};
int h(state a)
{
int cnt=0;
for(int i = 0;i < 9; i ++)
{
if(a.pos != i)
cnt += manhattan[((a.sta>>(3*(8-i)))&7)+1][i+1];
}
return cnt;
}
class cmp
{
public:
bool operator () (int u, int v)
{
return st[u].f > st[v].f;
}
};
int convert(int a[],state &b)
{
b.sta=0;
for(int i = 0; i < 9; i ++)
{
if(a[i]!=0)
b.sta |=((a[i]-1)<24-i*3));
else
{
b.pos = i;
b.sta |=(a[i]<24-i*3));
}
}
return 1;
}
state exchange(state a,int pos)
{
int temp = 7<9-pos)*3);
state s;
s.sta = a.sta;
temp = temp & a.sta;
temp = ((temp>>((9-pos)*3))<9-a.pos-1)*3));
s.sta |= temp;
s.sta &= ~(7<9-pos)*3));
s.pos = pos-1;
return s;
}
int search(state a)
{
int index = a.sta%MAXN;
bool flag = true;
while(flag)
{
if(!st[index].sta)
{
st[index].sta = a.sta;
st[index].pos = a.pos;
flag = false;
}
else if(!(st[index].sta^a.sta)&&!(st[index].pos^a.pos))
flag = false;
else
index = (index+1)%MAXN;
}
return index;
}
int main()
{
freopen("in.txt","r",stdin);
clock_t start,end;
for(int j=0;j<8;j++)temp[j] = j+1;
temp[8]=0;
convert(temp,target);
while(1)
{
int i = 0;
memset(st,0,sizeof(st));
char ch;
while((ch=getchar())!='
')
{
if(ch<='9'&&ch>='0')
sou[i++] = ch - '0';
else if(ch=='x')
sou[i++] =0;
}
convert(sou,source);
start = clock();
i = search(source);
st[i].f = h(st[i]);
priority_queue<int,vector<int>,cmp>q;
q.push(i);
int index;
int count = 0;
while(!q.empty())
{
count++;
index = q.top();
q.pop(); //!!!!
if(!(st[index].sta^target.sta)&&st[index].pos == target.pos)
{
printf("%d
",st[index].step);
break;
}
for(int j = 0; j < 4; j ++)
{
if(d[st[index].pos][j])
{
int flag = search(exchange(st[index],d[st[index].pos][j]));
if(!st[flag].step||st[flag].step > st[index].step + 1)
{
st[flag].step = st[index].step + 1;
st[flag].f = st[flag].step + h(st[flag]);
q.push(flag);
}
}
}
}
while(!q.empty())q.pop();
end = clock();
printf("Time:%dms
state number:%d
",end-start,count);
}
system("pause");
return 0;
}
#include
#include
#include
#include
#define FUCK puts("fuck!")
#define STOP system("pause")
#define MAXN 388211
using namespace std;
struct state{
int sta,pos;
}source,target;
int temp[10],tar[10],sou[10];
int pathLimit;
int cnt;
int d[9][4]={{0,4,0,2},{0,5,1,3},{0,6,2,0},{1,7,0,5},{2,8,4,6},{3,9,5,0},{4,0,0,8},{5,0,7,9},{6,0,8,0}};
int h(state a)
{
int temp = target.sta;
int cnt=0;
for(int i = 0;i < 9; i ++)
{
if(a.pos==target.pos)
{
if(!(((temp>>(3*i))&7)^((a.sta>>(3*i))&7)))
cnt++;
}
else
{
if(!(((temp>>(3*i))&7)^((a.sta>>(3*i))&7))&&((a.sta>>(3*i))&7))
cnt++;
}
}
return 9-cnt;
}
int convert(int a[],state &b)
{
b.sta=0;
for(int i = 0; i < 9; i ++)
{
if(a[i]!=0)
b.sta |=((a[i]-1)<24-i*3));
else
{
b.pos = i;
b.sta |=(a[i]<24-i*3));
}
}
return 1;
}
state exchange(state a,int pos)
{
int temp = 7<9-pos)*3);
state s;
s.sta = a.sta;
temp = temp & a.sta;
temp = ((temp>>((9-pos)*3))<9-a.pos-1)*3));
s.sta |= temp;
s.sta &= ~(7<9-pos)*3));
s.pos = pos-1;
return s;
}
bool IDAStar(state &a,int depth,int diff,int prepos)
{
cnt++;
if(!(a.sta^target.sta)&&a.pos == target.pos)
{
printf("%d
",depth);
return true;
}
if(depth >= pathLimit) return false;
if( depth + diff > pathLimit ) return false;
for(int j = 0; j < 4; j ++)
{
if(d[a.pos][j] == prepos+1) continue;
if(d[a.pos][j])
{
state next = exchange(a,d[a.pos][j]);
if(IDAStar(next,depth+1, h(next),a.pos))
return true;
}
}
return false;
}
int main()
{
freopen("in.txt","r",stdin);
clock_t start,end;
int diff = 0;
for(int j=0;j<8;j++)temp[j] = j+1;
temp[8]=0;
convert(temp,target);
while(1)
{
int i = 0;
char ch;
while((ch=getchar())!='
')
{
if(ch<='9'&&ch>='0')
sou[i++] = ch - '0';
else if(ch=='x')
sou[i++] =0;
}
start = clock();
cnt = 0;
convert(sou,source);
pathLimit = h(source);
diff = pathLimit;
while(!IDAStar(source,0,diff,-1))pathLimit++;
end = clock();
printf("Time:%dms
state number:%d
",end-start,cnt);
}
system("pause");
return 0;
}
manhattan 거리 함수 기반 검색:
#include
#include
#include
#include
#define FUCK puts("fuck!")
#define STOP system("pause")
#define MAXN 388211
using namespace std;
struct state{
int sta,pos;
}source,target;
int temp[10],tar[10],sou[10];
int pathLimit;
int d[9][4]={{0,4,0,2},{0,5,1,3},{0,6,2,0},{1,7,0,5},{2,8,4,6},{3,9,5,0},{4,0,0,8},{5,0,7,9},{6,0,8,0}};
int manhattan[10][10] = // i Manhattan
{
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1, 0, 1, 2, 1, 2, 3, 2, 3, 4},
{-1, 1, 0, 1, 2, 1, 2, 3, 2, 3},
{-1, 2, 1, 0, 3, 2, 1, 4, 3, 2},
{-1, 1, 2, 3, 0, 1, 2, 1, 2, 3},
{-1, 2, 1, 2, 1, 0, 1, 2, 1, 2},
{-1, 3, 2, 1, 2, 1, 0, 3, 2, 1},
{-1, 2, 3, 4, 1, 2, 3, 0, 1, 2},
{-1, 3, 2, 3, 2, 1, 2, 1, 0, 1},
{-1, 4, 3, 2, 3, 2, 1, 2, 1, 0}
};
int h(state a)
{
int cnt=0;
for(int i = 0;i < 9; i ++)
{
if(a.pos != i)
cnt += manhattan[((a.sta>>(3*(8-i)))&7)+1][i+1];
}
return cnt;
}
int convert(int a[],state &b)
{
b.sta=0;
for(int i = 0; i < 9; i ++)
{
if(a[i]!=0)
b.sta |=((a[i]-1)<24-i*3));
else
{
b.pos = i;
b.sta |=(a[i]<24-i*3));
}
}
return 1;
}
state exchange(state a,int pos)
{
int temp = 7<9-pos)*3);
state s;
s.sta = a.sta;
temp = temp & a.sta;
temp = ((temp>>((9-pos)*3))<9-a.pos-1)*3));
s.sta |= temp;
s.sta &= ~(7<9-pos)*3));
s.pos = pos-1;
return s;
}
bool IDAStar(state &a,int depth,int diff,int prepos)
{
if(!(a.sta^target.sta)&&a.pos == target.pos)
{
printf("%d
",depth);
return true;
}
if(depth > pathLimit) return false;
if( depth + diff > pathLimit ) return false;
for(int j = 0; j < 4; j ++)
{
if(d[a.pos][j] == prepos+1) continue;
if(d[a.pos][j])
{
state next = exchange(a,d[a.pos][j]);
if(IDAStar(next,depth+1, h(next),a.pos))
return true;
}
}
return false;
}
int main()
{
freopen("in.txt","r",stdin);
clock_t start,end;
int diff = 0;
for(int j=0;j<8;j++)temp[j] = j+1;
temp[8]=0;
convert(temp,target);
while(1)
{
int i = 0;
char ch;
while((ch=getchar())!='
')
{
if(ch<='9'&&ch>='0')
sou[i++] = ch - '0';
else if(ch=='x')
sou[i++] =0;
}
start = clock();
convert(sou,source);
pathLimit = h(source);
diff = pathLimit;
while(!IDAStar(source,0,diff,-1))pathLimit++;
end = clock();
printf("Time:%dms
depthlimit:%d
",end-start,pathLimit);
}
system("pause");
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
폭력 (납 계) - ACdream 1068제목 링크:http://acdream.info/problem?pid=1068 제목: 제목 보기 분석: 폭력, (MD, 직접 검색 하면 돼) AC 코드:...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.