⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 noj 1042 改棋盘.txt

📁 ACM资料大集合
💻 TXT
字号:
#include <stdio.h> 
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;

//NOJ 1042 改棋盘
//假设法

#define NMAX 17
#define MAX 500
//定义修改格子的意思
#define CHN tqizi[hang-1][lie]=(tqizi[hang-1][lie]+1)%2
#define CHS tqizi[hang+1][lie]=(tqizi[hang+1][lie]+1)%2
#define CHE tqizi[hang][lie+1]=(tqizi[hang][lie+1]+1)%2
#define CHW tqizi[hang][lie-1]=(tqizi[hang][lie-1]+1)%2
#define CHM tqizi[hang][lie]=(tqizi[hang][lie]+1)%2
int qizi[NMAX][NMAX];
int done[NMAX][NMAX];
int final[NMAX][NMAX];
int tqizi[NMAX][NMAX];//第i次假设第1行修改情况时,棋盘的情况

void change(int hang,int lie,int hnum,int lnum)
{
	CHM;//本身的格子肯定要改
	//周围的格子根据边界情况修改
	if(1!=hang&&hnum!=hang&&1!=lie&&lnum!=lie) {CHN;CHS;CHE;CHW;return;}
	else if(hang==1&&lie==1) {CHS; CHE; return;}
	else if(hang==1&&lie==lnum) {CHS; CHW; return;}
	else if(hang==hnum&&lie==1) {CHN; CHE; return;}
	else if(hang==hnum&&lie==lnum) {CHN; CHW; return;}
	else if(hang==1) {CHS;CHW;CHE;}
	else if(hang==hnum) {CHN;CHW;CHE;}
	else if(lie==1) {CHN;CHS;CHE;}
	else if(lie==lnum) {CHN;CHS;CHW;}
} 

void print(int hnum,int lnum)
{	//第i次假设第1行修改情况时,打印棋盘的移动情况
	int i,j;
	for(i=1;i<=hnum;i++)
	{
		for(j=1;j<=lnum;j++)
			cout<<done[i][j]<<" ";
		cout<<endl;
	}
//	system("pause");
}
int cal(int hnum,int lnum)
{
	int asume,i,j,k,tt,shuzu[NMAX],win,min,cishu,p,q;
	asume=pow(2,lnum);
	win=0;
	min=MAX;
	memset(final,0,sizeof(final));
	for(i=0;i<asume;i++)
	{	//第i次假设第1行修改情况
		for(p=1;p<=hnum;p++)
			for(q=1;q<=lnum;q++)
				tqizi[p][q]=qizi[p][q];
		cishu=0;
		memset(done,0,sizeof(done));
		j=lnum-1;
		tt=i;
		while(j>=0)
		{//利用二进制数存储第i次时,第1行应该如何修改
			shuzu[j]=tt%2;
			tt/=2;
			j--;
		}
		for(j=0;j<lnum;j++)
		{
			if(shuzu[j]==1) 
			{	//如果二进制的某数位上为1,则修改改位
				change(1,j+1,hnum,lnum);
				done[1][j+1]=1;//标记修改
				cishu++;//修改次数加1
			}
		}
		for(j=2;j<=hnum;j++)
		{	//剩下的j-1行,要根据上一行的情况进行修改
			for(k=1;k<=lnum;k++)
			{
				if(tqizi[j-1][k]==1) 
				{	//上一行的同一列上为1时,肯定要对改位修改
					change(j,k,hnum,lnum);
					done[j][k]=1;
					cishu++;
				}
			}
		}
		for(j=1;j<=lnum;j++)
		{	
			if(tqizi[hnum][j]==1) break;
		}
//		cout<<"i="<<i<<endl;
//		print(hnum,lnum);
		if(j>lnum) 
		{	//只有当最后一列都为1时,表示一开始对第1行的假设是可行的
			if(min>cishu) 
			{	//取最小的次数
				min=cishu;
				for(p=1;p<=hnum;p++)
				{
					for(q=1;q<=lnum;q++)
						final[p][q]=done[p][q];//final[][]为最后的修改结果
				}

			}
			win=1;
		}
	}
	return win;
}

int main()
{
	int i,j,hnum,lnum;
	while(scanf("%d%d",&hnum,&lnum)!=EOF)
	{
	for(i=1;i<=hnum;i++)
	{
		for(j=1;j<=lnum;j++)
			scanf("%d",&qizi[i][j]);
	}
	if(cal(hnum,lnum)==0) cout<<"IMPOSSIBLE"<<endl;
	else
	{
		for(i=1;i<=hnum;i++)
		{
			for(j=1;j<=lnum;j++)
				printf("%d ",final[i][j]);
			cout<<endl;
		}
	}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -