P1911 L 国的战斗之排兵布阵

这篇文章描述了一个编程问题,要求在给定军营数量和指挥营位置的情况下,生成一个呈现L形的军营布局,每个军营按照行先列后的顺序编号,指挥营用0表示。程序给出了C++代码实现,展示了如何使用深度优先搜索算法来排列军营号。
摘要由CSDN通过智能技术生成

# L 国的战斗之排兵布阵

## 题目背景

L 国即将与 I 国发动战争!!

## 题目描述

L 国的指挥官想让他的每一个军营都呈现出国徽形——L 形(方向无所谓)。当然,他的指挥营除外(这叫做个性),他想不出该怎么排,就这样,这任务又变成了你的······

## 输入格式

一行三个数:$n$,$x$,$y$ 表示军营大小为  $2^n$,指挥营在 $(x,y)$ 的位置上。

## 输出格式

$2^n$ 行,每行 $2^n$ 个数,表示军营号(按先行后列顺序)指挥营用 $0$ 表示。

## 样例 #1

### 样例输入 #1

```
4 1 3
```

### 样例输出 #1

```
1 1 0 2 3 3 4 4 5 5 6 6 7 7 8 8
1 9 2 2 3 10 10 4 5 11 11 6 7 12 12 8
13 9 9 14 15 15 10 16 17 11 18 18 19 19 12 20
13 13 14 14 21 15 16 16 17 17 18 22 22 19 20 20
23 23 24 21 21 25 26 26 27 27 28 28 22 29 30 30
23 31 24 24 25 25 32 26 27 33 33 28 29 29 34 30
35 31 31 36 37 32 32 38 39 39 33 40 41 34 34 42
35 35 36 36 37 37 38 38 43 39 40 40 41 41 42 42
44 44 45 45 46 46 47 43 43 48 49 49 50 50 51 51
44 52 52 45 46 53 47 47 48 48 54 49 50 55 55 51
56 52 57 57 58 53 53 59 60 54 54 61 62 62 55 63
56 56 57 64 58 58 59 59 60 60 61 61 65 62 63 63
66 66 67 64 64 68 69 69 70 70 71 65 65 72 73 73
66 74 67 67 68 68 75 69 70 76 71 71 72 72 77 73
78 74 74 79 80 75 75 81 82 76 76 83 84 77 77 85
78 78 79 79 80 80 81 81 82 82 83 83 84 84 85 85
```

## 提示

$1\le n\le10$,$1\le x,y\le2^n$。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1050
using namespace std;
int s=1,cnt=1;
int n,dx,dy,cc,flag;
int map[MAXN][MAXN];
bool visit[MAXN][MAXN];
void ddf(int a,int b,int c,int d,int e){
    if(c==1) return;
    c/=2;
    if(d<a+c&&e<b+c){
        ddf(a,b,c,d,e);
        ddf(a,b+c,c,a+c-1,b+c);
        ddf(a+c,b,c,a+c,b+c-1);
        ddf(a+c,b+c,c,a+c,b+c); 
        cc++;
        map[a+c][b+c]=cc;
        map[a+c][b+c-1]=cc;
        map[a+c-1][b+c]=cc;
    }
    if(d<a+c&&e>=b+c){
        ddf(a,b,c,a+c-1,b+c-1);
        ddf(a,b+c,c,d,e);
        ddf(a+c,b,c,a+c,b+c-1);
        ddf(a+c,b+c,c,a+c,b+c);
        cc++;
        map[a+c][b+c]=cc;
        map[a+c][b+c-1]=cc;
        map[a+c-1][b+c-1]=cc;
    }
    if(d>=a+c&&e<b+c){
        ddf(a,b,c,a+c-1,b+c-1);
        ddf(a,b+c,c,a+c-1,b+c);    
        ddf(a+c,b,c,d,e);
        ddf(a+c,b+c,c,a+c,b+c);
        cc++;
        map[a+c-1][b+c-1]=cc;
        map[a+c-1][b+c]=cc;
        map[a+c][b+c]=cc;
    }
    if(d>=a+c&&e>=b+c){
        ddf(a,b,c,a+c-1,b+c-1);
        ddf(a,b+c,c,a+c-1,b+c);
        ddf(a+c,b,c,a+c,b+c-1);
        ddf(a+c,b+c,c,d,e);
        cc++;
        map[a+c-1][b+c-1]=cc;
        map[a+c][b+c-1]=cc;
        map[a+c-1][b+c]=cc;
    }
}
void dnum(int x,int y){
    map[x][y]=cnt;
    visit[x][y]=1;
    if(!visit[x+1][y]&&map[x+1][y]==flag)    dnum(x+1,y);
    if(!visit[x-1][y]&&map[x-1][y]==flag)    dnum(x-1,y);
    if(!visit[x][y+1]&&map[x][y+1]==flag)    dnum(x,y+1);
    if(!visit[x][y-1]&&map[x][y-1]==flag)    dnum(x,y-1);
}
int main(){
    scanf("%d%d%d",&n,&dx,&dy);
    while(n){ s*=2;n--; }
    ddf(1,1,s,dx,dy);
    visit[dx][dy]=1;
    for(int i=1;i<=s;i++){
        for(int j=1;j<=s;j++){
            if(visit[i][j]){
                printf("%d ",map[i][j]);
                continue;
            }
            flag=map[i][j];
            dnum(i,j);
            cnt++;
            printf("%d ",map[i][j]);
        }
        cout<<endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内测人员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值