宿舍里的故事之五子棋(dfs)

题目描述

宿舍里好多好多有趣的事!

7890653今天看到不知何时流行的五子棋,在宿舍里拿个本子,画一些格子,一个棋盘就做好了。

当7890653把目光放到棋上,突发奇想……

在一个 5*5 的棋盘内,放上n颗棋子,其中(5<=n<=25);

这n颗棋子可以不同的放到任何一个地方---在棋盘内。于是呼,便会有五颗棋子排成一行,或一列,或两条对角线,不同的放法,就会出现多少排五子的排列。

本题你要做的是,给你一个n,你找出不同放法出现的排列(设为k),如:n=11

有(1是棋子,0是空格)

1 1 1 0 0         1 1 1 1 1
1 1 0 0 0         1 1 1 1 0
1 1 0 0 0         1 1 0 0 0
1 1 0 0 0         0 0 0 0 0
1 1 0 0 0   k=2;  0 0 0 0 0   k=1;

只有这两种k值,(注意k不重复),你要输出的便是k值的和。

也就是1+2=3

输入格式

输入一个数n, 占一行!

其中(5<=n<=25);

输出格式

输出一个k值的总和!(想也不用想k的范围是1<=k<=12的);

样例输入

11

样例输出

3

解题思路:

        这道题比较麻烦,需要先做一个五子棋摆放横竖的子函数,我就起名为cnm,其次为了好记录是否下棋,我们把a定义为布尔型,在1~5的循环内判断横竖摆放是否为真,为真计数器就加加,在循环外判断是否为对角线,如果为真用一个布尔型变量记录为真(这里我用的是d).

        接下来就是子函数(dfs),我们要先判断放不了的情况,也就是说n+1或i==6,还需要一个判断就是sum==n+1,就是放不下棋子或都用完的情况,这是就可以调用cnm,这个循环结束后就可以用return ;跳到上一层,完了之后我们还要判断j用完的情况,就是一个if(j==6)然后递归,如果没有用完的话就else,else内我们要先记录a[i][j]为真,接着就是递归,再记录a[i][j]为假,继续递归,最后记录a[i][j]为假,这就是子函数部分。

        最后是主函数,输入不用多说,需要一个1~12(大于12)的循环,因为k的范围是1~12,在里面判断d[i]是否为真,如果为真就用一个计数器+=i,最后我们只需要输出那个计数器即可。(这题真令人痛苦)

        直接上代码!!!!!

#include <iostream>
#include <cstring>
using namespace std;
bool a[6][6],d[15];
int ans=0,n;
void cnm()
{
	int s=0;
	for(int i=1;i<=5;i++){
        if(a[i][1]&&a[i][2]&&a[i][3]&&a[i][4]&&a[i][5]) s++;
        if(a[1][i]&&a[2][i]&&a[3][i]&&a[4][i]&&a[5][i]) s++; 
	}
    if(a[1][1]&&a[2][2]&&a[3][3]&&a[4][4]&&a[5][5]) s++;
	if(a[1][5]&&a[2][4]&&a[3][3]&&a[4][2]&&a[5][1]) s++;
	d[s]=true;
}
void dfs(int i,int j,int sum){
	if(i==6||sum==n+1)
	{
		if(sum==n+1)
		{
	 		cnm();
		}
        return ;
	}
	if(j==6) dfs(i+1,1,sum);
	else
	{
		a[i][j]=1;
		dfs(i,j+1,sum+1);
		a[i][j]=0;
		dfs(i,j+1,sum);
		a[i][j]=0;
	}
}
int main(){
	cin>>n;
	dfs(1,1,1);
    for(int i=1;i<=15;i++)
	{
    	if(d[i])ans+=i;
	}
	cout<<ans;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值