取数游戏(dfs)

https://www.luogu.com.cn/problem/P1123原题链接
解法:使用深度优先遍历。

#include
using namespace std;
using gg=long long;
int max_sum=0;
int X[]={-1,0,1};
int Y[]={-1,0,1};
int visited[100][100];
int n,m;
bool justice(int i,int j)//判断其周围八个点是否有被访问的
{
    for(int k=0;k<3;k++)
    {
        for(int p=0;p<3;p++)
        {
            int x=i+X[k];
            int y=j+Y[p];
            if(visited[x][y]) return false;
        }
    }
    return true;
}
void dfs(vector<vector<int> > &v,int i,int j,int res)
{
    if(i==n)//如果行达到了末端,则刷新输出
    {
        max_sum=max(max_sum,res);
        return;
    }
    int next_x=i; //下一个x
    int next_y=j+1; //下一个y
    if(next_y==m) //如果y到达最右边,则访问下一行并且把y置0
    {
        next_y=0;
        next_x+=1;
    }
    if(justice(i,j))//如果当前元素周围没有被访问的,则访问当前元素
    {
        visited[i][j]=1;
        dfs(v,next_x,next_y,res+v[i][j]);
        visited[i][j]=0;//当前元素也可以不被访问,搜索更多的路径
        //这里如果没有这一步可能会导致63如果被访问之后92就再也不能访问了,因为92周围有63;这个和下面一句是联合起来的,缺一不可。
    }
    dfs(v,next_x,next_y,res);//不管当前元素周围是否有被访问的都需要访问下一个


}
int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(NULL);
    gg t;
    cin>>t;
    for(int p=0;p<t;p++)
    {
        cin>>n>>m;
        max_sum=0;
        vector<vector<int> > v(n,vector<int>(m));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                cin>>v[i][j];
            }
        }
        dfs(v,0,0,0);
        cout<<max_sum<<"\n";

    }
    return 0;
}

你可能感兴趣的:(csp,深度优先,c++,算法)