算法竞赛宝典:分治算法 循环比赛

 

 样例:输入2

样例:输出  

1    2   3   4

2    1   4   3

3    4    1   1

4    3    2   1

m<=5

其实这道题可以打个表,因为数据范围确实有点小,一共才五种情况

刚开始呢,我想要模拟来着,也是可以的,可以用到数独的思想

每行不能有重复的,每列不能有重复的

这个跟数独不一样的是,没有九宫格,所以搜索起来能简单点

我在这里呢,就用这种方法写一下

因为网上有大佬用分治算法了,我就另辟蹊径了

直接暴力模拟一下

因为时间效率过得去,我就写了一种及其笨拙但是很能让新手看懂的(因为我也是新手)

#include<bits/stdc++.h>
using namespace std;

int m;
int n;
int ok=0;
int a[50][50];
int lie[50][50];
int hang[50][50];

void print()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++) cout<<a[i][j]<<" ";
		cout<<endl;
	}
}//输出函数

void dfs(int x,int y)
{
	if(ok==1) return;
	if(x==n+1)
	{
		print();
		ok=1;
		return;
	}
	if(y==n+1)
	{
		dfs(x+1,1);
		return;
	}
	if(a[x][y]!=-1)
	{
		dfs(x,y+1);
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(hang[x][i]==0&&lie[y][i]==0)
		{
			hang[x][i]=1;
			lie[y][i]=1;
			a[x][y]=i;
			dfs(x,y+1);
			hang[x][i]=0;
			lie[y][i]=0;
			a[x][y]=-1;
		}//里面需要有个回溯算法的东西,因为第一遍穷举不可能完全就是正确答案,所以设上标记后需要释放标记
	}
}

int main()
{
	cin>>m;
	n=pow(2,m);//偷个懒,直接调用pow函数求幂
	memset(a,-1,sizeof(a));
	for(int i=1;i<=n;i++)
	{
		a[1][i]=i;//第一个人已经安排ok了 
		a[i][1]=i;//第一列的人填上 
	}
    for(int i=1;i<=n;i++)
    {
    	a[i][n]=n-i+1;//每行最后一个 
    	a[n][i]=n-i+1;//最后一行每一列 
	}
    for(int i=n;i>=2;i--)
    {
    	int temp=a[n][i];
    	a[temp][i]=n;
	}//序号为1和序号为n的特殊处理一下就行
	memset(hang,0,sizeof(hang));
	memset(lie,0,sizeof(lie));//这两个数组相当于是标记数组,所以初始化
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i][j]==-1) continue;
			hang[i][a[i][j]]=1;
			lie[j][a[i][j]]=1;
		}
	}
	dfs(1,1);
    return 0;
} 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值