没有利用题目所造成的key的特殊性质,结果–比赛的时候和蛇一起状态压缩超内存。
int dp[][][][] -> setdp[][] 试图这样做,减少空间的浪费 结果超时.
用优先队列的搜索到达结果后可直接:
return s.t;
否则应该:
res=min(res,s.t );
优先列队下可以有这个剪枝
if(s.t<vis[s.x][s.y ][s.s1 ][s.s2 ]){
continue;
}
然好像并没有发挥什么作用
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
#include<set>
#include<queue>
using namespace std;
const int INF=0x7fffffff;
//set<int>dp[102][102];
int vis[102][102][(1<<5)+1][12];
/*struct point{
int s1,s2;
}p[(1<<4)*(10)]; 根据状态序号可以直接反映射出状态 ,此题无需用到*/
int map2[1<<6][12];
void init(){
memset(map2,0,sizeof(map2));
int state_snake=1<<5;
int state_key=11;
int cnt=0;
for(int i=0;i<=state_snake;i++){
for(int j=0;j<=state_key;j++){
// p[cnt].s1 =i; 此题无需用到
// p[cnt].s2 =j; 此题无需用到
map2[i][j]=cnt++;
}
}
}
char map1[102][102];
int idx [102][102];
int n,m,snake_num;
struct state{
int x,y,s1,s2,t;
state(int _x1,int _y1,int _s1,int _s2,int _t):x(_x1),y(_y1),s1(_s1),s2(_s2),t(_t){}
state(){}
/* bool operator<(const state& other) const
{
return t>other.t;
}*/
};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int find_snake(int i,int j){
return idx[i][j];
}
int find_key(int i,int j){
return idx[i][j];
}
int bfs(int kx,int ky){
int res=INF;
//queue<state> que;
priority_queue<state> que;
while(!que.empty()) que.pop();
int size1=(1<<snake_num);
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
for(int u=0;u<=size1;u++){
for(int v=0;v<=m;v++){
vis[i][j][u][v]=-1;
}
}
}
}
/* for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
dp[i][j].clear();
}
} */
que.push(state(kx,ky,0,0,0));
dp[kx][ky].insert(map2[0][0]);
//int kkk=0;
while(!que.empty()){
state s=que.top(); que.pop();
//printf("%d %d %d %d %d \n",kkk++,s.x,s.y ,s.s1 ,s.s2 );
if(map1[s.x][s.y]=='T' && (s.s2==m) ) {
res=min(res,s.t );
// return s.t;
}
int nx,ny;
for(int i=0;i<4;i++){
nx=s.x +dir[i][0];
ny=s.y +dir[i][1];
if(nx<0 || nx>=n || ny<0 || ny>=n || map1[nx][ny]=='#')
continue;
int tmp=s.t;
state news=s;
news.x =nx,news.y =ny;
if(map1[nx][ny]=='S'){
int which=find_snake(nx,ny);
if((news.s1 &(1<<which) )==0){
tmp++;
news.s1 |= 1<<which ;
}
}
if(map1[nx][ny]>='1'&&map1[nx][ny]<='9')
{
int which=find_key(nx,ny);
if( news.s2 +1 == which )
{
news.s2++;
}
}
/* int newid=map2[news.s1][news.s2];
if(!dp[news.x ][news.y ].count(newid)){
dp[news.x][news.y].insert(newid);
que.push(state(news.x ,news.y ,news.s1 ,news.s2,tmp+1));
} */
if(vis[news.x][news.y][news.s1 ][news.s2 ]==-1){
vis[news.x][news.y][news.s1 ][news.s2 ]=tmp+1;
que.push(state(news.x ,news.y ,news.s1 ,news.s2,tmp+1));
}
}
}
return res;
}
int main(){
freopen("F:\\123.txt","r",stdin);
//freopen("D:\\output.txt","r",stdout);
init();
while(scanf("%d%d",&n,&m)!=EOF){
if(n==0&&m==0) break;
for(int i=0;i<n;i++){
scanf("%s",map1[i]);
}
int kx,ky;
snake_num=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(map1[i][j]>='0'&&map1[i][j]<='9'){
idx[i][j]= (int)(map1[i][j]-'0');
}
if(map1[i][j]=='S'){
idx[i][j]=snake_num++;
}
if(map1[i][j]=='K'){
kx=i;ky=j;
}
}
}
// printf("Looking %d \n",snake_num);
int res= bfs(kx,ky);
if(res==INF){
printf("impossible\n");
}else{
printf("%d\n",res);
}
}
return 0;
}
题外话:
struct newdp{
set<int> s;
}dp[][]
和
set<int >dp[][] 好像是一样的吧
debug初始的错误
for(int i=0;i<(1<<6);i++){
for(int j=0;j<=11;j++){
dp[i][j].set1.clear();
}
}
应该是下面才对
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
dp[i][j].clear();
}
struct state{
int x,y,s1,s2,t; !!(t一开始没写进去)
state(int _x1,int _y1,int _s1,int _s2,int _t):x(_x1),y(_y1),s1(_s1),s2(_s2),t(_t){}
state(){}
/* bool operator<(const state& other) const
{
return t>other.t;
}*/
};