poj 2965二进制

1.题意

有一个4*4的(+,-)符号矩阵,改变一个元素的符号,所在行列都反转最少次数,让所有符号变成 - 号 并打印出符号位置;

2,思路

  • 翻转的执行先后序列不影响结果;
  • 每个点最多一次,有翻和不翻的选择;
  • 0-0xFFFF表示矩阵状态,看最后状态是不是0x3FFFF,我们用0代表+,1代表-;

3,代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

int chess, step;
bool flag = false; 
int map[5][5];
int xx[20], yy[20];//记录路径
bool panduan(){//判断函数
	return chess == 0XFFFF ? true : false;//全部为- 时 就是16个1 的二进制 0xFFFF;
} 
void fanzhuan(int bit){//翻转函数,bit为我们要对第bit个棋子进行翻转,为了方便计算坐标(0~15)表示每个棋子
	chess = chess ^ (1 << bit);
	//自身翻转,比如有4个棋子现在是0110, 翻转第2个棋子, chess^(1<<1) 0110^10=0100 
	int tx = bit / 4;//通过bit 计算在矩阵中第bit个坐标
	int ty = bit % 4;
	for(int i = 0; i < 4; i++){
		chess = chess ^ (1 << (tx * 4 + i));// 同一行 
	}
	for(int i = 0; i < 4; i++){
		chess = chess ^ (1 << (i * 4 + ty));// 同一列 
	}
	return ;
}

void dfs(int bit, int count){
	if(count == step){//当前步数到达了我们计划要的步数
		flag = panduan();//判断是否全 - 
		return;
	}
	if(flag || bit > 15) return ;//bit >15 超过16个或者已经找到了答案
	
	xx[count] = bit / 4;//记录count步的位置,count可以被覆盖的
	yy[count] = bit % 4;
	fanzhuan(bit);//翻转bit位
	dfs(bit + 1, count + 1);
	
	fanzhuan(bit);//不翻转 翻两次就变回来了嘛,相当于回溯
	dfs(bit + 1, count);//不翻就不加1
}
int main(){
	char str;
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			cin >> str;
			if(str == '-'){//'-' 为开 
				chess = chess ^ (1 << ((i * 4) + j));//二进制表示状态 
			}
			
		}
	}
	
	for(step = 0; step <= 16; step++){
		dfs(0, 0);//最少步数,最多16或者没有解,从0步开始试探,就可以保证最少步数
		if(flag)
			break;
	}
	cout << step << endl;
	for(int i = 0; i < step; i++){
		cout << xx[i] + 1 <<" " << yy[i] + 1 << endl;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值