Base DFS (poj 1321, hdoj 2553, hdoj 5113)

White also learned a dfs today's questions, want to record, hey hey hey

capacity 1321

Chessboard
Time Limit: 1000MS Memory Limit: 10000K
Total on the Submissions: 85425 Accepted: 39462

Description

In a checkerboard given shape (the shape may be irregular) placed above the pieces, pieces no difference. The requirements of any two pieces can not be placed in the same row or the same column in the board when the display is required, program for solving a given board size and shape, placing the k pieces of all possible placement scheme C.

Input

Test input comprising a plurality of sets of data.
The first line of each data are two positive integers, NK, separated by a space, and indicates the number of the board will be described in a matrix of n * n, and put the pieces. n <= 8, k <= n
when the end of input is represented by -1 -1.
Then n lines describe the shape of a checkerboard: n characters per line, where # represents the board area, indicates a blank area (extra blank line data is guaranteed not to appear or blank columns).

Output

For each set of data, one line of output is given, the number of output display program C (data guarantee C <2 ^ 31).

Sample Input

2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1

Sample Output

2
1

White new to DFS, not quite understand this thing, I feel good magic recursive layer by layer , or need more understanding, more practice ah! DFS code is shorter than the BFS, but not easy to understand, is still much to do problems, ex.

#include <iostream>
#include <string.h>
using namespace std;
char maps[9][9];//读取棋盘
int lie[9],ans=0,k,n,m=0;
void dfs(int row)
{
    if(row>n)//超出棋盘范围则返回
        return;
    if(m==k)//当搜索长度与要求的相同时,返回
    {
        ans++;
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(maps[row][i]=='#'&&lie[i]==0)
        {
            lie[i]=1;
            m++;
            dfs(row+1);
            m--;//恢复之前的状态
            lie[i]=0;
        }
    }
    dfs(row+1);//下一行
}
int main()
{
    while(cin>>n>>k&&n!=-1)
    {
        ans=0;m=0;
        memset(maps,0,sizeof(maps));
        memset(lie,0,sizeof(lie));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                cin>>maps[i][j];
        }
        dfs(0);
        cout<<ans<<endl;
    }
}

Restore state where need more understanding, then it is to find the right point after layer recursive return, then the next layer to be restored to a natural state is not visited.

2553 hdoj N Queens Problem

Subject to the effect: this question is relatively simple N Queens, namely N Queens 10.00, placing n queens on the board to make them different rows and different columns, different diagonals, how many inquiries have placement methods.

Solution: This problem need to use dfs search, it is important to go back and pruning , ie removing the placement method does not meet the requirements. First fight the table, if you do not hit the table time out, and then use dfs Search, and then check function to determine whether to meet the requirements, here in different diagonal from (i, j) syncline diagonal walk a step, the new coordinates ( r, c) there are four cases: (ia, ja), ( ia, j + a), (i + a, ja), (i + a, j + a). Sum up, | ir | = | jc |

AC Code:

#include <iostream>
#include <string.h>
#include <cmath>
using namespace std;
int col[12]={0};
int ans[12]={0};
int n,sum=0;
bool check(int c,int r)
{
    for(int i=0;i<r;i++)//从每一排检查该列有没有已经放下的
    {
        if(col[i]==c||abs(col[i]-c)==abs(i-r))
            return false;
    }
    return true;
}
void dfs(int r)
{
    if(r==n)
    {
        sum++;
        return;
    }
    for(int i=0;i<n;i++)//每一列
    {
        if(check(i,r))
        {
            col[r]=i;
            dfs(r+1);
        }
    }
}
int main()
{
    for(n=0;n<=10;n++)//先打表
    {
        memset(col,0,sizeof(col));
        sum=0;
        dfs(0);//从第0排开始搜索
        ans[n]=sum;
    }
    while(cin>>n&&n)
    {
        cout<<ans[n]<<endl;
    }
}

5113 hdoj Black And White
(Most of this problem is to write emm, but when pruning viewed dalao code)

Title effect: coloring problem, two adjacent regions can not be the same color (i.e., one side of a shared area), and specifies the number of occurrences of each color, and the number of blocks and the total sum of the number of various colors appears. Write a coloring method consistent with the meaning of the questions.

Solution: after all, the first time to write their own dfs, the middle there have been many minor bugs. It is recommended that when writing an array of maps, index starts at 1, more convenient when determining whether you can put some color in this area. The whole idea is to use dfs search, from (1,1) to start, then turn down, apply a color to judge if this program is not feasible, the recursive will be rolled back. If the search to last this is feasible, then you need to add a rollback return 1.
When pruning, if the remaining number of blocks of a certain color is generally less than the remaining number of colors, this scheme necessarily feasible (see dalao code is said to own painting came out).

AC Code:

#include <iostream>
#include <string.h>
using namespace std;
int maps[6][6];
int num[26];
int tmp[26];
int n,m,k;
int dfs(int r,int c)
{
    int flag=0;
    if(r==n+1)
    {
        return 1;
    }
    int sum=(n*m-(r-1)*m-c+2)/2; //剪枝
    for(int i=1;i<=k;i++)
    {
        if(num[i]-tmp[i]>sum)
            return 0;
    }
    for(int i=1;i<=k;i++)
    {
        if(tmp[i]>=num[i]||maps[r][c-1]==i||maps[r-1][c]==i)
            continue;
        maps[r][c]=i;
        tmp[i]++;
        if(c==m)
            flag=dfs(r+1,1);
        else
            flag=dfs(r,c+1);
        if(flag==1)//回退时,如果方案可行,则需要返回1
            return 1;
        tmp[i]--; //不要忘记回到之前的状态
        maps[r][c]=0;
    }
    return 0;
}
int main()
{
    int w,t=0;
    cin>>w;
    while(w--)
    {
        memset(maps,0,sizeof(maps));
        memset(tmp,0,sizeof(tmp));
        t++;
        cin>>n>>m>>k;
        for(int i=1;i<=k;i++)
        {
            cin>>num[i];
        }
        cout<<"Case #"<<t<<":"<<endl;
        int flag=dfs(1,1);
        if(flag==0)
            cout<<"NO"<<endl;
        else
        {
            cout<<"YES"<<endl;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    cout<<maps[i][j];
                    if(j==m)
                        cout<<endl;
                    else
                        cout<<" ";
                }
            }
        }
    }
}
Published 32 original articles · won praise 12 · views 1383

Guess you like

Origin blog.csdn.net/qq_18873031/article/details/98495609