第七届 蓝桥杯 方格填数 dfs
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。 (左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
方法一:遍历
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int map[][];
int ans=;
int Abs(int i,int j)//判断 8个方向
{
if(abs(map[i-][j]-map[i][j])==)
return ;
if(abs(map[i+][j]-map[i][j])==)
return ;
if(abs(map[i][j+]-map[i][j])==)
return ;
if(abs(map[i][j-]-map[i][j])==)
return ;
if(abs(map[i-][j-]-map[i][j])==)
return ;
if(abs(map[i+][j-]-map[i][j])==)
return ;
if(abs(map[i-][j+]-map[i][j])==)
return ;
if(abs(map[i+][j+]-map[i][j])==)
return ;
return ;
}
int f()//判断相邻的数是否连续
{
if(Abs(,)&&Abs(,)&&Abs(,)&&Abs(,)&&Abs(,)&&Abs(,))
return ;
return ;
}
int main()
{
memset(map,-,sizeof(map));
int a[] = {,,,,,,,,,};
do{
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
map[][]=a[];
ans+=f();
}while(next_permutation(a,a+));
cout<<ans<<endl;
return ;
}
方法二: dfs
#include <stdio.h>
#include <stdlib.h> int ans = , flag[] = {}; int Check(int a[][], int x, int y)
{
static int dx[] = {, -, -, -}, dy[] = {-, -, , }; for(int i = ; i < ; i ++)
if( (x + dx[i] >= && x + dx[i] < ) && (y + dy[i] >= && y + dy[i] < ) )
{
if( == abs(a[x][y] - a[ x + dx[i] ][ y + dy[i] ]))
return ;
} return ;
} void dfs(int a[][], int x, int y)
{
if( == x && == y){
ans ++;
return ;
} for(int num = ; num <= ; num ++)
if(!flag[num]){
a[x][y] = num;
flag[num] = ; if(Check(a, x, y)){
if(y + < )
dfs(a, x, y + );
else
dfs(a, x + , );
}
flag[num] = ;
}
} int main()
{
int a[][] = {-};
dfs(a, , );
printf("%d", ans);
return ;
}
方法三:
看到这题第一个想到的方法就是回溯,就很像八皇后,能填进去就填,填不进去就看下一个位置(我做的是0---9不重复使用)
我感觉这题麻烦就在判断上
1.首先要判断一个点的8个方向相减的绝对值是否为1,为1不能填入,不为1判断是否使用过这个数,没使用填入 进行下一个位置
2.如果填入的位置到达最后一列应该换行看下一行的第一个位置进行判断
3.填到最后每一个情况总sum++就行了
上代码
#include<iostream>
using namespace std;
int a[][];
int num = ;
int v[] = {};
int pd(int k, int i, int j){//这个就是判断啦。。写的有点繁琐
if (i->= && (a[i - ][j] == k - || a[i - ][j] == k + ) )
return ;
if (j->= && (a[i][j - ] == k + || a[i][j - ] == k - ) )
return ;
if (i->= && j->= && (a[i - ][j - ] == k + || a[i - ][j - ] == k - ))
return ;
if (i->= && j+< && (a[i - ][j + ] == k + || a[i - ][j + ] == k - ))
return ;
if (j + < && (a[i][j + ] == k + || a[i][j + ] == k - ))
return ;
if (i + < && (a[i + ][j] == k + || a[i + ][j] == k - ))
return ;
if (i + < && j - >= && (a[i + ][j - ] == k + || a[i + ][j - ] == k - ))
return ;
if (i + < && j + < && (a[i + ][j + ] == k + || a[i + ][j + ] == k - ))
return ;
return ;
}
void f(int i, int j){
if (i == &&j==){//已经填入到最后一个说明这种情况满足,num++
num++;
return;
}
for (int k = ; k <= ; k++){
if (pd(k, i, j)&&v[k]==) {//判断8个方向是否能填入,并且是否用过
v[k] = ;
a[i][j] = k;
if (j == )//到达最后一列记得换行
f(i + , );
else
f(i, j + );
a[i][j] = -;
v[k] = ;
}
}
}
int main(){
for (int i = ; i < ; i++)//这里我将所有数赋值-9,因为第一个和最后一个不需要赋值,避免干扰
for (int j = ; j < ; j++)
a[i][j] = -;
f(, );
printf("%d", num);
return ;
}
#include <bits/stdc++.h>
using namespace std; /*本来要判断八个格子,
*但是由于是从左往右从上往下填的,
*只要判断左、左上、上、右上
*/
const int dx[]={,-,-,-};
const int dy[]={-,-,,};
const int INF=1e9;
bool used[];
int ans=;
int a[][]; bool alright(int n,int x,int y)
{
for (int i=;i<;i++) {
int xx=x+dx[i],yy=y+dy[i];
if (xx<||yy<||xx>||yy>) continue;
if (abs(n-a[xx][yy])==) return false;
}
return true;
} void dfs(int x,int y)
{
if (x==&&y==) {
ans++;
return;
}
for (int i=;i<=;i++) {
if (!used[i]&&alright(i,x,y)) {
a[x][y]=i;
used[i]=true;
if (y==) dfs(x+,);
else dfs(x,y+);
used[i]=false;
a[x][y]=-INF;
}
}
} int main()
{
for (int i=;i<=;i++) {
for (int j=;j<=;j++) {
a[i][j]=-INF;
}
}
dfs(,);
printf("%d\n",ans);
return ;
}
第七届 蓝桥杯 方格填数 dfs的更多相关文章
- java实现第七届蓝桥杯方格填数
方格填数 题目描述 如下的10个格子 +--+--+--+ | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | +--+--+--+ (如果显示 ...
- java实现第七届蓝桥杯七星填数
七星填数 如图[图1.png]所示. 在七角星的14个节点上填入1~14 的数字,不重复,不遗漏. 要求每条直线上的四个数字之和必须相等. 图中已经给出了3个数字. 请计算其它位置要填充的数字,答案唯 ...
- 蓝桥杯 方格填数 DFS 全排列 next_permutation用法
如下的10个格子(参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案? 请填写表示方案数目的整数.注意:你提交的应该是一个 ...
- java实现第六届蓝桥杯五星填数
五星填数 如[图1.png]的五星图案节点填上数字:1~12,除去7和11. 要求每条直线上数字和相等. 如图就是恰当的填法. 请你利用计算机搜索所有可能的填法有多少种. 注意:旋转或镜像后相同的算同 ...
- java实现第七届蓝桥杯凑平方数
凑平方数 把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的. 比如:0, 36, 5948721 再比如: 1098524736 1, 25, 6390784 0, 4, 28 ...
- 2016年第七届蓝桥杯C/C++程序设计本科B组省赛
/* 2016年第七届蓝桥杯C/C++程序设计本科B组省赛 煤球数目(结果填空) 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形) ...
- 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告
2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...
- 2016年第七届蓝桥杯c/c++省赛B组
2016年第七届蓝桥杯c/c++省赛B组 声明:以下答案是我自己做的.不能保证正确,须要參考正确答案的请到其它地方找. 第一题 :煤球数目 题目叙述: 有一堆煤球,堆成三角棱锥形.详细: 第一层放1个 ...
- java算法 第七届 蓝桥杯B组(题+答案) 6.方格填数
6.方格填数 (结果填空) 如下的10个格子 (如果显示有问题,也可以参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案 ...
随机推荐
- vector创建二位数组
默认初始化vector vector<vevtor<int> > arr(row, vector<int>(col, 0)); //指定行大小为row,列为col, ...
- Two (DP)
题意:求两串数字有多少个相同的子串,子串不要求连续. 思路:直接DP,dp[i][j] 代表A串长度为i.B串为j时满足条件的子串个数.转移dp[i][j] = dp[i -1][j] + dp[i] ...
- python 七段管模块
python 七段管模块 def drawGap(): #绘制数码管间隔 turtle.penup() turtle.fd(5) def drawLine(draw): #绘制单段数码管 drawGa ...
- 2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165305 Exp1 PC平台逆向破解 实验1-1直接修改程序机器指令,改变程序执行流程 先输入objdump -d 20165305pwn2查看反汇编代码 ...
- 2.2JAVA基础复习——JAVA语言的基础组成运算符和语句
JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...
- vue路由详解
自己看vue文档,难免有些地方不懂,自己整理一下,主要是vue-router具体实现的操作步骤. 安装 直接下载/CDN https://unpkg.com/vue-router/dist/vue-r ...
- Sql Server语句大全
T-SQL语句大全 --跳转到SQL myDemo USE [SQL myDemo] go --声明变量id declare @id int --为变量赋值:直接赋值 --将cid为3的cname值赋 ...
- 关于Python的协程问题总结
协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生 ...
- python3 error 机器学习 错误
AttributeError: 'NoneType' object has no attribute 'sqrt' 这个错误其实是因为 plt.scatter(x[:,0],x[:,1],x[:,2] ...
- gjt常用命令---chalee
Git常用命令 一. git 基本操作流程 1. 从远程分支拉取并创建新的分支 git pull origin [远程分支名]:[本地分支名] // 从远程分支迁出本地分支,并切换到新的本地分支 gi ...