dfs学习

棋盘问题

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。 
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
当为-1 -1时表示输入结束。 
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

Sample Input

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

Sample Output

2
1

题意:在给定的可放棋区域放K个棋,最多有多少中方法,限制是任意两个棋不能在同行或同列。

和八皇后差不多,代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, k, ans, res;
char v[10][10];
int a[10];
void dfs(int x){
    if(res == k){
        ans++;
        return;
    }
    if(x >= n) return;
    for(int i = 0; i < n; i ++){
        if(!a[i] && v[x][i] == ‘#‘){
            a[i] = 1;
            res ++;
            dfs(x+1);
            res--;
            a[i] = 0;
        }
    }
    dfs(x+1);
}
int main(){
    while(~scanf("%d%d",&n,&k)){
        if(n == -1 && k == -1)break;
        ans = res = 0;
        for(int i = 0; i < n; i ++) cin >> v[i];
        dfs(0);
        cout << ans << endl;
    }
}

LETTERS

A single-player game is played on a rectangular board divided in R rows and C columns. There is a single uppercase letter (A-Z) written in every position in the board. 
Before the begging of the game there is a figure in the upper-left corner of the board (first row, first column). In every move, a player can move the figure to the one of the adjacent positions (up, down,left or right). Only constraint is that a figure cannot visit a position marked with the same letter twice. 
The goal of the game is to play as many moves as possible. 
Write a program that will calculate the maximal number of positions in the board the figure can visit in a single game.

Input

The first line of the input contains two integers R and C, separated by a single blank character, 1 <= R, S <= 20. 
The following R lines contain S characters each. Each line represents one row in the board.

Output

The first and only line of the output should contain the maximal number of position in the board the figure can visit.

Sample Input

3 6
HFDFFB
AJHGDH
DGAGEH

Sample Output

6题意就是从第一行第一列开始走,看最多能走几步,只能四个方向(上,下,左,右)而且走过的字母不能在走了。没什么好说的,见代码:

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, maxn, dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
char a[25][25];
bool vis[25][25], ap[30];//vis标记地图,ap标记字母
void dfs(int x, int y, int ans){
    for(int i = 0; i < 4; i ++){
        int nx = x + dx[i], ny = y + dy[i];
        if(0 <= nx && nx < n && 0 <= ny && ny < m && vis[nx][ny] == false && ap[a[nx][ny]-‘A‘] == false){
            vis[nx][ny] = true;
            ap[a[nx][ny]-‘A‘] = true;
            //cout << nx << ‘ ‘ << ny << ‘ ‘ << ans << endl;
            dfs(nx, ny, ans+1);
            vis[nx][ny] = false;
            ap[a[nx][ny]-‘A‘] = false;
        }
        else maxn = max(maxn, ans);
    }
}
int main(){
    while(~scanf("%d%d",&n,&m)){
        maxn = 1;
        for(int i = 0; i < n; i ++) cin >> a[i];
        vis[0][0] = true;
        ap[a[0][0]-‘A‘] = true;
        dfs(0,0,1);
        cout << maxn << endl;
    }
}

Red and Black

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can‘t move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach by repeating the moves described above.

Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

‘.‘ - a black tile 
‘#‘ - a red tile 
‘@‘ - a man on a black tile(appears exactly once in a data set) 
The end of the input is indicated by a line consisting of two zeros.

Output

For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).

Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#[email protected]#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
[email protected]
###.###
..#.#..
..#.#..
0 0

Sample Output

45
59
6
13

题意:从@开始可以从‘.’上走,到不能从‘#’上走,求最多能走几步。直接遍历,代码:

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, ans;
char a[50][50];
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
void dfs(int x, int y){
    a[x][y] = ‘#‘;
    for(int i = 0; i < 4; i ++){
        int nx = x + dx[i], ny = y + dy[i];
        if(0 <= nx && nx < n && 0 <= ny && ny < m && a[nx][ny] == ‘.‘){
            ans ++;
            dfs(nx,ny);
        }
    }
}
int main(){
    while(~scanf("%d%d",&m,&n)&&m&&n){
        ans = 1;
        for(int i = 0; i < n; i ++) cin >> a[i];
        int nx, ny;
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < m; j ++){
                if(a[i][j] == ‘@‘){
                    nx = i; ny = j;
                    goto tt;
                }
            }
        }
        tt: ;
        dfs(nx, ny);
        cout << ans << endl;
    }
}

Kalevitch and Chess

A famous Berland‘s painter Kalevitch likes to shock the public. One of his last obsessions is chess. For more than a thousand years people have been playing this old game on uninteresting, monotonous boards. Kalevitch decided to put an end to this tradition and to introduce a new attitude to chessboards.

As before, the chessboard is a square-checkered board with the squares arranged in a8?×?8 grid, each square is painted black or white. Kalevitch suggests that chessboards should be painted in the following manner: there should be chosen a horizontal or a vertical line of 8 squares (i.e. a row or a column), and painted black. Initially the whole chessboard is white, and it can be painted in the above described way one or more times. It is allowed to paint a square many times, but after the first time it does not change its colour any more and remains black. Kalevitch paints chessboards neatly, and it is impossible to judge by an individual square if it was painted with a vertical or a horizontal stroke.

Kalevitch hopes that such chessboards will gain popularity, and he will be commissioned to paint chessboards, which will help him ensure a comfortable old age. The clients will inform him what chessboard they want to have, and the painter will paint a white chessboard meeting the client‘s requirements.

It goes without saying that in such business one should economize on everything — for each commission he wants to know the minimum amount of strokes that he has to paint to fulfill the client‘s needs. You are asked to help Kalevitch with this task.

Input

The input file contains 8 lines, each of the lines contains 8 characters. The given matrix describes the client‘s requirements, W character stands for a white square, and B character — for a square painted black.

It is guaranteed that client‘s requirments can be fulfilled with a sequence of allowed strokes (vertical/column or horizontal/row).

Output

Output the only number — the minimum amount of rows and columns that Kalevitch has to paint on the white chessboard to meet the client‘s requirements.

Example

Input

WWWBWWBWBBBBBBBBWWWBWWBWWWWBWWBWWWWBWWBWWWWBWWBWWWWBWWBWWWWBWWBW

Output

3

Input

WWWWWWWWBBBBBBBBWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW

Output

1

题意:在8*8图上,最少画几画,B是画的,W是没画的,可以画一行或者一列。说是dfs,其实就是一道规律题,每输入一行,就求下B的数量,如果是8的话,就可以当成画了一行,不是8的话,就是话了多少列了,等8行都是8个时就要特判下。

#include <iostream>
using namespace std;
char a[10];
int main(){
    int res = 0, ans = 0;
    for(int i = 0; i < 8; i ++){
        cin >> a;
        int k = 0;
        for(int i = 0; i < 8; i ++){
            if(a[i] == ‘B‘) k++;
        }
        //cout << k << endl;
        if(k == 8) ans ++;
        else res = k;
    }
    if(ans == 8) cout << ans << endl;
    else cout << ans + res << endl;
    return 0;
}

President‘s Office

President of Berland has a very vast office-room, where, apart from him, work his subordinates. Each subordinate, as well as President himself, has his own desk of a unique colour. Each desk is rectangular, and its sides are parallel to the office walls. One day President decided to establish an assembly, of which all his deputies will be members. Unfortunately, he does not remember the exact amount of his deputies, but he remembers that the desk of each his deputy is adjacent to his own desk, that is to say, the two desks (President‘s and each deputy‘s) have a common side of a positive length.

The office-room plan can be viewed as a matrix with n rows and m columns. Each cell of this matrix is either empty, or contains a part of a desk. An uppercase Latin letter stands for each desk colour. The ?period? character (?.?) stands for an empty cell.

Input

The first line contains two separated by a space integer numbers nm (1?≤?n,?m?≤?100) — the length and the width of the office-room, and c character — the President‘s desk colour. The following n lines contain m characters each — the office-room description. It is guaranteed that the colour of each desk is unique, and each desk represents a continuous subrectangle of the given matrix. All colours are marked by uppercase Latin letters.

Output

Print the only number — the amount of President‘s deputies.

Example

Input

3 4 RG.B..RR.TTT.

Output

2

Input

3 3 Z....H...Z

Output

0

题意:在给定的n行m列中,求于c相邻的字母有多少。两个或两个以上相同的字母当成一个。代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};
int vis[30];
char a[110][110];
int n, m, ans = 0;
char c;
void dfs(int x, int y){
    for(int i = 0; i < 4; i++){
        int nx = x + dx[i], ny = y + dy[i];
        if(0 <= nx && nx < n && 0 <= ny && ny < m && isalpha(a[nx][ny]) && a[nx][ny] != c && vis[a[nx][ny] - ‘A‘] == 0){
            vis[a[nx][ny]-‘A‘] = 1;
            ans++;
            a[nx][ny] = ‘.‘;
        }
    }
}

int main(){
    while(cin>>n>>m>>c){
        memset(vis, 0, sizeof(vis));
        ans = 0;
        for(int i = 0; i < n; i ++) cin >> a[i];
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < m; j ++){
                if(a[i][j] == c){
                    dfs(i, j);
                }
            }
        }
        cout << ans << endl;
    }
}

时间: 2024-11-16 07:59:08

dfs学习的相关文章

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

ACM学习历程—HDU5269 ZYB loves Xor I(位运算 &amp;&amp; dfs &amp;&amp; 排序)(BestCoder Round #44 1002题)

Problem Description Memphis loves xor very musch.Now he gets an array A.The length of A is n.Now he wants to know the sum of all (lowbit(Ai xor Aj) (i,j∈[1,n]) We define that lowbit(x)=2^k,k is the smallest integer satisfied ((x and 2^k)>0)Specially,

【算法学习笔记】61.回溯法 DFS SJTU OJ 1106 sudoku

虽然DLX可以提高效率....但是对于NPC问题也不用太追求效率了,而且还只有一个测试点. 所以 只要DFS不断的填入,直到空格全部被填满:要注意的是DFS中全局变量的更新和恢复. 至于存储的方法,只要考虑每一行每一列每一个小块的不重复即可. #include <iostream> #include <cstring> using namespace std; int cnt = 0 ;//表示剩余的要填的空格的数目 struct point { int x,y; }; point

ACM学习历程——HDU5202 Rikka with string(dfs,回文字符串)

Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them: One day, Yuta got a string which contains n letters but Rikka lost it in accident. Now

ACM学习历程—HDU1716 排列2(dfs &amp;&amp; set容器)

Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束. Output 对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔. 每组输出数据间空一行,最后一组数据后面没有空行. Sample Input 1 2 3 4 1 1 2 3 0 1

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 马上又要秋招了,赶紧复习下基础知识.这里复习下二叉树.图的深搜与广搜.从图的遍历说起,图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序访问"图"中所有的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现: 广度优先(优先走最近的),用的数据结构是队列,主要是迭代实现: 对于深搜,由于递归往往可以方便的利

hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,s,flag; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; char mapp[25][25],road[1000],d[5] = {"DURL"}; bool check(int x,int y) { if(x < 0 || x &g

DFS中的奇偶剪枝学习笔记

奇偶剪枝学习笔记 描述 编辑 现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点, s | | | + — — — e 如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8: s — — — — — + | + | + — — — e 如图,为一般情况下非最短路径的任意走法举例,step2=14: step2-step1=6,偏移路径为6,偶数(易证): 结