120MS AC
看过别人的代码,看过比他短的,但是也有一百多行,像这种长代码的,如果说是学模仿别人的代码,意义实在不大,如果等级不过还不如去做一些简单的搜索,先练练后面再做;关键还是注意事项,我也是看了别人的注意事项才改出来的;
大致思路:
1,以DFS为主板,因为石头就5个,像求全排列一样写,时间复杂度 5!*4*4*4*4*4;5!是石头排列的种类,4*4*4*4*4是每个石头分别有四种方向;128840
2,有时候不推石头比推石头得到的钱更多;
3.用BFS询问,石头能不能被推动;
4,每次推完石头,用BFS先把可以拣到的钱全部拣了,标记为空地,这里最关键,实力不行我整整思考了一天,这里我用到hh[7][22]记录每层改变的位置,当返回的时候你是要返回去的;
5,最后比较每种情况输去的最大值
#include<cstdio>
#include<cstring>
#include<algorithm>
#include <queue>
using namespace std;
int N,M,l,w,sum,cp,num;
char a[22][22];
int b[22];
int fx[4][2]={1,0,0,1,-1,0,0,-1};
struct point
{
int x,y;
}hh[7][22],ff[22],head,tail;
int bd(int x1,int y1)
{
if(x1<0||y1<0||x1>=N||y1>=M)
return 1;
return 0;
}
int bfs1(int kk,int kkk,int f,int f1)\\是否将石头推动
{
if(kk==f&&kkk==f1)
return 1;
queue<point>q;
head.x=kk;
head.y=kkk;
q.push(head);
int i,j;
int c[14][14];
for(i=0;i<=12;i++)
for(j=0;j<=12;j++)
c[i][j]=1;
c[kk][kkk]=0;
while(!q.empty())
{
head=q.front();
q.pop();
for(i=0;i<4;i++)
{
tail.x=head.x+fx[i][0];
tail.y=head.y+fx[i][1];
if(tail.x<0||tail.y<0||tail.x>=N||tail.y>=M)
continue;
if(a[tail.x][tail.y]=='X'||a[tail.x][tail.y]=='O')
continue;
if(c[tail.x][tail.y])
{
c[tail.x][tail.y]=0;
if(tail.x==f&&tail.y==f1)
return 1;
q.push(tail);
}
}
}
return 0;
}
int bfs(int l1,int l2,int ll)\\将可以拣的钱,全部拣了
{
queue<point>q;
head.x=l1;
head.y=l2;
q.push(head);
int i,j;
int c[22][22];
for(i=0;i<=20;i++)
for(j=0;j<=20;j++)
c[i][j]=1;
c[l1][l2]=0;
int fff1=0;
while(!q.empty())
{
head=q.front();
q.pop();
for(i=0;i<4;i++)
{
tail.x=head.x+fx[i][0];
tail.y=head.y+fx[i][1];
if(tail.x<0||tail.y<0||tail.x>=N||tail.y>=M)
continue;
if(a[tail.x][tail.y]=='X'||a[tail.x][tail.y]=='O')
continue;
if(c[tail.x][tail.y])
{
c[tail.x][tail.y]=0;
if(a[tail.x][tail.y]=='C')
{
hh[ll][fff1].x=tail.x;
hh[ll][fff1].y=tail.y;
fff1++;
a[tail.x][tail.y]='.';
}
q.push(tail);
}
}
}
return fff1;
}
void hs(int fff1,int ll)
{
for(int i=0;i<fff1;i++)
a[hh[ll][i].x][hh[ll][i].y]='C';
}
void dfs(int kk,int kkk,int gg)\\全摆列 当石头为5时一共128840种不同情况
{
int i,j;
int x1,y1,x2,y2;
int sum1;
if(cp==sum)
return;
if(gg>cp)
cp=gg;
for(i=0;i<num;i++)
{
if(!b[i])continue;
b[i]=0;
for(j=0;j<4;j++)
{
x1=ff[i].x+fx[j][0];
y1=ff[i].y+fx[j][1];
x2=ff[i].x-fx[j][0];
y2=ff[i].y-fx[j][1];
if(x1<0||y1<0||x1>=N||y1>=M)
continue;
if(a[x2][y2]=='X'||a[x2][y2]=='C'||a[x2][y2]=='O'||bd(x2,y2))
continue;
if(a[x1][y1]=='X'||a[x1][y1]=='O')
continue;
if(bfs1(kk,kkk,x1,y1))
{
a[ff[i].x][ff[i].y]='.';
a[x2][y2]='X';
sum1=bfs(ff[i].x,ff[i].y,i);
dfs(ff[i].x,ff[i].y,gg+sum1);
hs(sum1,i); \\我就是错在这里
a[ff[i].x][ff[i].y]='O';
a[x2][y2]='.';
}
}
b[i]=1;
}
}
int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
cp=0;
num=0;
sum=0;
scanf("%d%d",&N,&M);
for(i=0;i<N;i++)
{
scanf("%s",a[i]);
for(j=0;j<M;j++)
{
if(a[i][j]=='C')
sum++;
if(a[i][j]=='S')
l=i,w=j;
if(a[i][j]=='O')
{
ff[num].x=i;
ff[num].y=j;
num++;
}
}
}
for(i=0;i<=20;i++)
b[i]=1;
cp=bfs(l,w,6);
if(cp!=sum)//当已经将石头拣完就不拣了 算是剪枝
dfs(l,w,cp);
printf("%d\n",cp);
}
}