[POJ]POJ2965(dfs)

题意:给出一个4*4的01方阵,每次可选择i,j使第i行和第j列状态取反,求全变成0的最小步数。

显然每个坐标最多选择一次,因此最多有2^16种选法,枚举最小步数dfs即可。

#include <cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long int LL;

#define st first
#define nd second
#define pb push_back
#define mp make_pair
#define pll pair <LL, LL>
#define pii pair <int, int>
#define rep(i,x) for(int i=1;i<=x;i++)

const int N = 1e5+7;
const int MX = 1e9+7;
const LL INF = 1e18+9LL;

char a[6][6];
int ans[20];

int check(){
	rep(i,4)
	rep(j,4)if(a[i][j]==‘+‘)return 0;
	return 1;
}

void make(int x,int y){
	rep(i,4)a[x][i]=(a[x][i]==‘+‘? ‘-‘:‘+‘);
	rep(i,4)a[i][y]=(a[i][y]==‘+‘? ‘-‘:‘+‘);
	a[x][y]=(a[x][y]==‘+‘? ‘-‘:‘+‘);
} 

int dfs(int s,int x,int y){
	if(!s||x>4)return check();
	if(4*(4-x)+5-y<s)return 0;
	int f;
	if(y<4){
	    f=dfs(s,x,y+1);
	    if(f)return 1;
 	    make(x,y);
	    f=dfs(s-1,x,y+1);
		if(f)ans[s]=x*10+y;
	    make(x,y);
	    return f;
	}

	else {
		f=dfs(s,x+1,1);
	    if(f)return 1;
	    make(x,y);

	    f=dfs(s-1,x+1,1);
		if(f)ans[s]=x*10+y;
	    make(x,y);
	    return f;
	}
} 

int main(){
	rep(i,4)scanf("%s",a[i]+1);
	for(int i=0;i<=16;i++){
		if(dfs(i,1,1)){
			cout<<i<<endl;
			for(int j=i;j>=1;j--){
				cout<<ans[j]/10<<" "<<ans[j]%10<<endl;
			}
			return 0;
		}
	}

	return 0;
}

原文地址:https://www.cnblogs.com/xutianshu/p/10157415.html

时间: 2024-11-09 10:39:58

[POJ]POJ2965(dfs)的相关文章

POJ 3321 DFS序+线段树

单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include <cstdio> 6: #include <cstring> 7: #include <cctype> 8: #include <algorithm> 9: #include <vector> 10: #include <iostream> 1

poj 1167 DFS

1 /* 2 题意:给出0-59的一排数字表示某一时刻出现了1辆bus,其中数字重复出现表示多辆bus同时出现,这些bus是 3 由多个bus线路组成的,每条线路都有一个时间间隔,而且同一线路的bus在0-59肯定会出现两次或以上,如果 4 有两条线路的间隔相同且到达时刻相同也算作两条不同的线路,问最少有多少条线路. 5 6 题解:DFS 7 这题是一题相对较难的搜索,关键在于找出状态以及剪枝: 8 对于每条bus线路都由开始时刻start和间隔interval组成,这样就找出了表示一条线路的状

Oil Deposits(poj 1526 DFS入门题)

http://poj.org/problem?id=1562 Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12595   Accepted: 6868 Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp wor

poj 1069 DFS+剪枝

1 /* 2 题意:给出一个边长为S的六边形,再给出n种边长不同的三角形,所有的长度均为整型,问这n种三角形是否 3 能够拼成这个六边形. 4 5 题解:DFS+剪枝 6 这题的关键是图的表示方法以及剪枝,图我用了一个二维数组直接表示: 7 111111111111111111111 8 111110000000000011111 9 111100000000000001111 10 111000000000000000111 11 110000000000000000011 12 100000

poj 2488 dfs

背景:就是简单的遍历全图搜索,但要注意两点: 1.一开始以为起点不同会有不同结果,所以就枚举了起点,但实际上只要能遍历全图就能把A1作为起点,因为遍历全图就是每个点都要走到,那么A1也要走到,既然可以走到A点,那么也可以从A点走到其它点. 2.题目中的字典序输出,不看看很能想到题意是先满足列,然后满足行,这样写出满足条件的方向数组即可. //poj 2488 #include<map> #include<set> #include<stack> #include<

poj 1190 DFS 不等式放缩进行剪枝

F - (例题)不等式放缩 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1190 Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱.当i < M时,要求Ri &

poj 1979 dfs

水过,注意边界不能超出. #include <iostream> using namespace std; int n, m, sx, sy, dir[4][2] = {0, -1, 0, 1, 1, 0, -1, 0}, count; char diagram[23][23]; void get_diagram(void) { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> diag

Channel Allocation (poj 1129 dfs)

Language: Default Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12367   Accepted: 6325 Description When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that ever

poj 3009 dfs

背景:dfs,再加点模拟,各种代码疏漏错误wa了三次!!也有变量名使用不规则照成的.比如临时变量我我就应该用temp,buffer,key,三个变量名来表示. 思路:每一个点四个方向的dfs,到达终点就判断最少步数. bfs的思路:这个是经典的最短路问题,但是缺点是,地图会改变而bfs没办法像dfs那样容易回溯,方法就是把地图直接放在每一个坐标上,也就是定义一个结构体: struct place{ int x,y,step; int diagram[M][M];//每一个坐标点都付一个图 } 我