题目不用解释了,给出箱子的箱子的终点,求箱子的起点以及人的起点,使得人把箱子推到终点需要的最长步数。
我是从终点向起点DP的,就要考虑一种特殊情况:箱子开始就只能在终点,不可能在其他任何位置。
状态转移比较麻烦,分为8种情况,详情看代码吧
1# include <iostream>
2# include <cstring>
3# include <queue>
4using namespace std;
5# define encode(r1,c1,r2,c2) (((((((r1)<<5)|(c1))<<5)|(r2))<<5)|(c2))
6# define getr1(pos) ((pos)>>15)
7# define getc1(pos) (((pos)>>10)&31)
8# define getr2(pos) (((pos)>>5)&31)
9# define getc2(pos) ((pos)&31)
10# define legal(r,c) (map[r][c]!='#')
11# define equal(r1,c1,r2,c2) ((r1)==(r2)&&(c1)==(c2))
12# define max(a,b) ((a)>(b)?(a):(b))
13int dp[2000000],n;
14char map[30][30];
15queue<int> q;
16int solve(int r,int c)
17{
18 int res=0;
19 if(r!=n-1&&map[r+1][c]!='#')
20 {
21 dp[encode(r,c,r+1,c)]=0;
22 q.push(encode(r,c,r+1,c));
23 }
24 if(r!=0&&map[r-1][c]!='#')
25 {
26 dp[encode(r,c,r-1,c)]=0;
27 q.push(encode(r,c,r-1,c));
28 }
29 if(c!=0&&map[r][c-1]!='#')
30 {
31 dp[encode(r,c,r,c-1)]=0;
32 q.push(encode(r,c,r,c-1));
33 }
34 if(c!=n-1&&map[r][c+1]!='#')
35 {
36 dp[encode(r,c,r,c+1)]=0;
37 q.push(encode(r,c,r,c+1));
38 }
39 while(!q.empty())
40 {
41 int boxr=getr1(q.front()),boxc=getc1(q.front()),perr=getr2(q.front()),perc=getc2(q.front());
42 if(!equal(r,c,boxr,boxc))res=max(res,dp[q.front()]);
43 q.pop();
44 if(perr!=n-1&&map[perr+1][perc]!='#'&&!equal(boxr,boxc,perr+1,perc)&&dp[encode(boxr,boxc,perr+1,perc)]==-1)
45 {
46 dp[encode(boxr,boxc,perr+1,perc)]=dp[encode(boxr,boxc,perr,perc)]+1;
47 q.push(encode(boxr,boxc,perr+1,perc));
48 }
49 if(perr!=0&&map[perr-1][perc]!='#'&&!equal(boxr,boxc,perr-1,perc)&&dp[encode(boxr,boxc,perr-1,perc)]==-1)
50 {
51 dp[encode(boxr,boxc,perr-1,perc)]=dp[encode(boxr,boxc,perr,perc)]+1;
52 q.push(encode(boxr,boxc,perr-1,perc));
53 }
54 if(perc!=0&&map[perr][perc-1]!='#'&&!equal(boxr,boxc,perr,perc-1)&&dp[encode(boxr,boxc,perr,perc-1)]==-1)
55 {
56 dp[encode(boxr,boxc,perr,perc-1)]=dp[encode(boxr,boxc,perr,perc)]+1;
57 q.push(encode(boxr,boxc,perr,perc-1));
58 }
59 if(perc!=n-1&&map[perr][perc+1]!='#'&&!equal(boxr,boxc,perr,perc+1)&&dp[encode(boxr,boxc,perr,perc+1)]==-1)
60 {
61 dp[encode(boxr,boxc,perr,perc+1)]=dp[encode(boxr,boxc,perr,perc)]+1;
62 q.push(encode(boxr,boxc,perr,perc+1));
63 }
64 if(equal(boxr,boxc,perr+1,perc)&&perr!=0&&map[perr-1][perc]!='#'&&dp[encode(boxr-1,boxc,perr-1,perc)]==-1)
65 {
66 dp[encode(boxr-1,boxc,perr-1,perc)]=dp[encode(boxr,boxc,perr,perc)]+1;
67 q.push(encode(boxr-1,boxc,perr-1,perc));
68 }
69 if(equal(boxr,boxc,perr-1,perc)&&perr!=n-1&&map[perr+1][perc]!='#'&&dp[encode(boxr+1,boxc,perr+1,perc)]==-1)
70 {
71 dp[encode(boxr+1,boxc,perr+1,perc)]=dp[encode(boxr,boxc,perr,perc)]+1;
72 q.push(encode(boxr+1,boxc,perr+1,perc));
73 }
74 if(equal(boxr,boxc,perr,perc+1)&&perc!=0&&map[perr][perc-1]!='#'&&dp[encode(boxr,boxc-1,perr,perc-1)]==-1)
75 {
76 dp[encode(boxr,boxc-1,perr,perc-1)]=dp[encode(boxr,boxc,perr,perc)]+1;
77 q.push(encode(boxr,boxc-1,perr,perc-1));
78 }
79 if(equal(boxr,boxc,perr,perc-1)&&perc!=n-1&&map[perr][perc+1]!='#'&&dp[encode(boxr,boxc+1,perr,perc+1)]==-1)
80 {
81 dp[encode(boxr,boxc+1,perr,perc+1)]=dp[encode(boxr,boxc,perr,perc)]+1;
82 q.push(encode(boxr,boxc+1,perr,perc+1));
83 }
84 }
85 return res;
86}
87int main()
88{
89 memset(dp,-1,sizeof(dp));
90 cin>>n;
91 for(int i=0;i<n;i++)
92 cin>>map[i];
93 int tr,tc;
94 for(int i=0;i<n;i++)
95 for(int j=0;j<n;j++)
96 if(map[i][j]=='*')
97 {
98 tr=i;
99 tc=j;
100 goto endloop;
101 }
102endloop:;
103 // if(n==2)
104 // cout<<0<<endl;
105 // else
106 cout<<solve(tr,tc)<<endl;
107 return 0;
108}
109
110