uva 639 Don't Get Rooked (暴力回溯 )

uva 639 Don‘t Get Rooked

In chess, the rook is a piece that can move any number of squares vertically or horizontally. In this problem we will consider small chess boards (at most 44)
that can also contain walls through which rooks cannot move. The goal is to place as many rooks on a board as possible so that no two can capture each other. A configuration of rooks is
legal provided that no two rooks are on the same horizontal row or vertical column unless there is at least one wall separating them.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of rooks
in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a board, calculates the maximum number of rooks that can be placed on the board in a legal configuration.

Input

The input file contains one or more board descriptions, followed by a line containing the number 0 that signals the end of the file. Each board description begins with a line containing a positive integer
n that is the size of the board; n will be at most 4. The next
n lines each describe one row of the board, with a `
.
‘ indicating an open space and an uppercase ` X‘ indicating a wall. There are no spaces in the input file.

Output

For each test case, output one line containing the maximum number of rooks that can be placed on the board in a legal configuration.

Sample Input

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

Sample Output

5
1
5
2
4

题目大意:求一个棋盘上最多能摆多少个車。

解题思路:回溯。

#include<stdio.h>
#include<string.h>
int gra[8][8], n, ans;
int check(int x, int y) {
	for (int i = x + 1; i <= n && gra[i][y] != 0; i++) {  //上
		if (gra[i][y] == -1) return 0;
	}
	for (int i = x - 1; i >= 1 && gra[i][y] != 0; i--) {   //下
		if (gra[i][y] == -1) return 0;
	}
	for (int i = y + 1; i <= n && gra[x][i] != 0; i++) {  //右
		if (gra[x][i] == -1) return 0;
	}
	for (int i = y - 1; i >= 1 && gra[x][i] != 0; i--) {   //左
		if (gra[x][i] == -1) return 0;
	}
	return 1;
}
void DFS(int a) {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (gra[i][j] == 1 && check(i, j)) {  //是否可以放置棋子, 是否不与其他棋子相对
				gra[i][j] = -1;
				DFS(a + 1);
				gra[i][j] = 1;
			}
		}
	}
	if (ans < a) ans = a;
}
int main() {
	while (scanf("%d", &n) == 1, n) {
		getchar();
		char temp;
		memset(gra, 0, sizeof(gra));
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				scanf("%c", &temp);
				if (temp == '.') gra[i][j] = 1;
				else gra[i][j] = 0;
			}
			getchar();
		}
		ans = 0;
		DFS(0);
		printf("%d\n", ans);
	}
	return 0;
}

uva 639 Don't Get Rooked (暴力回溯 )

时间: 2024-10-28 21:08:00

uva 639 Don't Get Rooked (暴力回溯 )的相关文章

uva 639 Don&#39;t Get Rooked ( 回溯 )

这道题确实是标准的回溯,果然还是早上比较清醒一些,昨天晚上想了好长一会儿都没有想起来,早上一会的功夫就A 了,估计也有昨天晚上的帮助...总感觉不想写太多私人的东西在这上面,因为这个是每个人都可以无条件访问的... 思路: 由于数据比较小,可以把每个元素都遍历一遍,回溯选择,最多4*4,还是很小的,我交的才1ms,1A.. 贴代码: #include<stdio.h> #include<string.h> #include<stdlib.h> int map[10][1

UVa 639 - Don&#39;t Get Rooked

题目:在n*n的方格里,放入几个喷火器,他们会攻击同行.同列的点,问做多能放多少个. 分析:图论,搜索,二分图匹配.本题可以利用搜索求解,这里我使用的是二分图匹配. 建图,把原图每行每列的不同的连续区间分别看成一个新图中的点xi与yj: 则边<xi,yj>表示原图中对应位置的点,原图中可以互相攻击的点就对应到新图中相同的xi与yj: 则新图中的二分图最大匹配即为,原图中不能相互攻击的最大摆放数量. 说明:图论关键就是建图. #include <iostream> #include

Don&#39;t Get Rooked UVA 639(八皇后问题变形)

说说: 这道题目类似于八皇后问题.有n*n的正方形棋盘,且n<=4.例如在n=4时,有下图所示的棋盘,其中每两个棋子不能放在同一行或者同一列,除非有围墙(黑色的格子)将它们隔开.求给定的棋盘,能放下的最多的棋子数目. 分析: 在八皇后问题中,我们对整个棋盘分成八行考虑的,每行插入一个棋子.所以对于这道题目解决方案也类似,同样是一行一行插入.但是与八皇后问题不同的是,本题中棋盘一行可能插入多个棋子,也可能没有棋子.所以在递归函数中,不仅要给出所要处理的行的信息,也要给出所要处理的列的信息,其实就是

UVA 152-Tree&#39;s a Crowd(暴力求解三维坐标求最短距离)

Tree's a Crowd Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description  Tree's a Crowd  Dr William Larch, noted plant psychologist and inventor of the phrase ``Think like a tree--Think Fig'' has invented a new

uva 11754 - Code Feat(中国剩余定理+暴力)

题目链接:uva 11754 - Code Feat 题目大意:求一个数N,给出C和S,表示有C个条件,每个条件有X 和 k,然后是该个条件的k个yi,即NmodX=yj,输出满足的最小的S个N,要求正整数. 解题思路:total为所有的k的乘积,也就是可以作为一组完整限定条件的可能数,当个确定条件可以用中国剩余定理处理.但是如果total太大的话,处理的情况比较多.不过total数大的时候,可以通过枚举N来判断,找到一组k/x最小的最为枚举基准,然后判断即可. #include <cstdio

uva 1069 - Always an integer(数学+暴力)

题目链接:uva 1069 - Always an integer 题目大意:给出一个多次多项式,问说是否对于任意正整数n来说结构均为整数. 解题思路:首先处理出字符串,然后枚举n从1到k+1判断即可,k为多项式中出现过的最大幂数指. P为多项式,d为除数,k为多项式中最大的次数 当k=0时,P中不存在n变量,所以直接计算判断即可 当k=1时,P是一次多项式,那么P(n+1)?P(n)=a,a为常数,也就是说P(i)为等差数列,如果首项P(1)和公差P(2)-P(1)为d的倍数即可,等价与判断P

UVA 617 - Nonstop Travel(数论+暴力枚举)

题目链接:617 - Nonstop Travel 题意:给定一些红绿灯,现在速度能在30-60km/h之内,求多少个速度满足一路不遇到红灯. 思路:暴力每一个速度,去判断可不可以,最后注意下输出格式即可 代码: #include <stdio.h> #include <string.h> #include <math.h> const double esp = 1e-6; int n, vis[105]; struct D { double l; int g, y,

UVA - 524 Prime Ring Problem(dfs回溯法)

UVA - 524 Prime Ring Problem Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbers  into each circle separately, and the sum of number

uva 1318 - Monster Trap(bfs+暴力)

题目链接:uva 1318 - Monster Trap 每条线段2个点,加上起点终点一个是202个点,暴力判断连点之间是否可达,可达建边.因为线段有厚度考虑,所以将线段延伸一点再处理,这样原本共用一端点的线段变成相交.特殊情况是三点共线,这是判断延伸后的点是否落在其他线段上,如果是就不考虑这个点.最后做一遍bfs. #include <cstdio> #include <cstring> #include <cmath> #include <vector>