问题 B: 三角棋盘上的N皇后
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]题目描述
下图,就是一个大小为6的三角形棋盘:
Figure 1给出的是皇后攻击范围的示例——每个皇后有三个方向可以自由攻击。
Figure 2给出的是在一个三角形棋盘上的不能互相攻击的4个皇后。
现在,你有一个三角形棋盘,棋盘上已经放置了几个互相不能攻击的皇后,请问棋盘上最多还能放多少个皇后,使得她们仍然不能互相攻击;并求出有多少种方案可以放这么多皇后。编程输出这两个数。
输入
第一行一个数字N,代表棋盘的大小。
接下来N行,第i行有i个字符。表示棋盘第i行的状态,‘.’表示空,‘*’表示有皇后。
输出
两行,每行一个数字,分别为在原来的棋盘上最多能放的皇后数量,和放置这么多皇后的方案种数。
样例输入 Copy
2 . ..样例输出 Copy
1 3提示
1<=N<=13
先看看经典的八皇后源代码
#include <stdio.h>
int Queenes[8]={0},Counts=0;
int Check(int line,int list){ //遍历该行之前的所有行
for (int index=0; index<line; index++) { //挨个取出前面行中皇后所在位置的列坐标
int data=Queenes[index];
if (list==data) { //如果在同一列,该位置不能放
return 0;
}
if ((index+data)==(line+list)) { //如果当前位置的斜上方有皇后,在一条斜线上,也不行
return 0;
}
if ((index-data)==(line-list)) { //如果当前位置的斜下方有皇后,在一条斜线上,也不行
return 0;
}
}
return 1;
//如果以上情况都不是,当前位置就可以放皇后
}
//输出语句
void print()
{
for (int line = 0; line < 8; line++)
{
int list;
for (list = 0; list < Queenes[line]; list++)
printf("0");
printf("#");
for (list = Queenes[line] + 1; list < 8; list++)
printf("0");
printf("\n");
}
printf("================\n");
}
void eight_queen(int line){ //在数组中为0-7列
for (int list=0; list<8; list++) {
if (Check(line, list)) { //对于固定的行列,检查是否和之前的皇后位置冲突
Queenes[line]=list; //不冲突,以行为下标的数组位置记录列数
if (line==7) { //如果最后一样也不冲突,证明为一个正确的摆法
Counts++; //统计摆法的Counts加1
print(); //输出这个摆法
Queenes[line]=0; //每次成功,都要将数组重归为0
return;
}
eight_queen(line+1); //继续判断下一样皇后的摆法,递归
Queenes[line]=0; //不管成功失败,该位置都要重新归0,以便重复使用。
}
}
}
int main() {
//调用回溯函数,参数0表示从棋盘的第一行开始判断
eight_queen(0);
printf("摆放的方式有%d种",Counts);
return 0;
}
这道题没有什么奇特之处 ,偷学长的代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define se second
#define fi first
const int N=1e6+5;
const ll mod=1e9+7;
typedef pair<int,int> pp;
char g[15][15];
int n,res[200],a[15],b[15],c[15];
void dfs(int cnt,int x,int y)
{
if(x<y){
x++,y=1;
}
if(x>n){
res[cnt]++;
return ;
}
if(!a[x]&&!b[y]&&!c[x-y]){
a[x]=b[y]=c[x-y]=1;
dfs(cnt+1,x,y+1);
a[x]=b[y]=c[x-y]=0;
}dfs(cnt,x,y+1);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",g[i]+1);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(g[i][j]=='*'){
a[i]=1;
b[j]=1;
c[i-j]=1;
}
}
}
dfs(0,1,1);
for(int i=100;i>=0;i--){
if(res[i]){
printf("%d\n%d\n",i,res[i]);
return 0;
}
}
return 0;
}
我不知道这个代码和上面有什么区别,居然错了
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define se second
#define fi first
const int N=1e6+5;
const ll mod=1e9+7;
int n,res[200],a[20],b[20],c[20];
void dfs(int cnt,int x,int y)
{
if(x<y) //换行
{
x++;
y=1;
}
if(x>n)
{
res[cnt]++;
return ;
}
if(!a[x]&&!b[y]&&!c[x-y])
{
a[x]=b[y]=c[x-y]=1;
dfs(cnt+1,x,y+1);
a[x]=b[y]=c[x-y]=0;
}
dfs(cnt,x,y+1);
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
string s;
cin>>s;
for(int j=1; j<=i; j++)
{
if(s[j-1]=='*')
{
a[i]=1;
b[i]=1;
c[i-j]=1;
}
}
}
dfs(0,1,1);
for(int i=100; i>=0; i--)
{
if(res[i])
{
printf("%d\n%d\n",i,res[i]);
return 0;
}
}
return 0;
}
/**************************************************************
Problem: 14886
User: 2019UPC110
Language: C++
Result: 答案错误
****************************************************************/