P9700 [GDCPC2023] Peg Solitaire 题解
题目传送门
思路
由于
每一次寻找一个当前存在棋子的格子,往上,下,左,右四个方向,判断合不合法,判断条件为题面中的图,若合法,就按题意走出一步,并继续搜索。
还有,注意回溯和处理边界!
时间复杂度为
AC code:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,ans;
bool vis[15][15];
void dfs(int p)
{
ans=min(ans,p);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
if(vis[i][j])
{
if(j>=3&&vis[i][j-1]&&!vis[i][j-2])//往左跳
{
vis[i][j-1]=0;
vis[i][j]=0;
vis[i][j-2]=1;
dfs(p-1);
vis[i][j-1]=1;
vis[i][j]=1;
vis[i][j-2]=0;
}
if(i>=3&&vis[i-1][j]&&!vis[i-2][j])//往上跳
{
vis[i-1][j]=0;
vis[i][j]=0;
vis[i-2][j]=1;
dfs(p-1);
vis[i-1][j]=1;
vis[i][j]=1;
vis[i-2][j]=0;
}
if(j<=m-2&&vis[i][j+1]&&!vis[i][j+2])//往右跳
{
vis[i][j+1]=0;
vis[i][j]=0;
vis[i][j+2]=1;
dfs(p-1);
vis[i][j+1]=1;
vis[i][j]=1;
vis[i][j+2]=0;
}
if(i<=n-2&&vis[i+1][j]&&!vis[i+2][j])//往下跳
{
vis[i+1][j]=0;
vis[i][j]=0;
vis[i+2][j]=1;
dfs(p-1);
vis[i+1][j]=1;
vis[i][j]=1;
vis[i+2][j]=0;
}
}
}
}
}
int main(){
int t;
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis)); //多测不清空,爆零两行泪
ans=6; //因为最多有六个棋子,所以初始化为六即可
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
{
int x,y;
cin>>x>>y;
vis[x][y]=1; //标记在此位置有一个棋子
}
dfs(k);
cout<<ans<<endl;
}
return 0;
}
评测记录