【JZOJ 3807】地砖铺设

本文介绍了一个关于游戏厅瓷砖布局的算法问题。主角Randy希望通过合理的布局使得房间内的正方形瓷砖既美观又避免了相同颜色相邻的情况。文章提供了一种贪心算法解决方案,并通过代码示例详细展示了算法的具体实现。

Description

在游戏厅大赚了一笔的Randy 终于赢到了他想要的家具。乘此机会,他想把自己的房间好好整理一
下。
在百货公司,可以买到各种各样正方形的地砖,为了美观起见,Randy 不希望同样颜色的正方形地
砖相邻。所以他找到了Tio 来帮忙解决这件事情。
Tio 很快解决了这个任务。然而,出于某种强迫症,她希望在地上按照长宽划分成网格后,逐行逐
列每一块的颜色组成的序列的字典序最小。她希望你帮忙验证一下她的方案。

Solution

这题用贪心,按顺序找到第一个空着的位置,求出当前点可以放的最小的字母,再扩展一圈(按当前位置为左上角的大一码的正方形),看看新扩展出来的区域能放的最小的字母是什么(越上越优先),如果一样就继续扩展,知道不行,

正确性显然,

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define OK(q,w) ((q)>0&&(w)>0&&(q)<=n&&(w)<=m)
using namespace std;
const int N=105;
int n,m;
int a[N][N];
int ans[N][N];
int Z[N];
int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void FZ(int q,int w,int n,int e)
{
    fo(i,q,q+n-1)fo(j,w,w+n-1)a[i][j]=e;
}
bool OK1()
{
    fo(i,1,n)fo(j,1,m)if(a[i][j]!=ans[i][j])return a[i][j]<ans[i][j];
    return 0;
}
bool NIL(int q,int w,int n)
{
    bool ans=1;
    fo(i,q,q+n-1)fo(j,w,w+n-1)
    {
        if(a[i][j])return 0;
    }
    return ans;
}
int MI(int q,int w)
{
    fo(i,1,30)Z[i]=0;
    fo(k,0,3)if(OK(q+fx[k][0],w+fx[k][1])&&a[q+fx[k][0]][w+fx[k][1]])Z[a[q+fx[k][0]][w+fx[k][1]]]=1;
    fo(i,1,30)if(!Z[i])return i;
}
void ss()
{
    int q=0,w;
    fo(i,1,n)
    {fo(j,1,m)if(!a[i][j]){q=i;w=j;break;}if(q)break;}
    if(!q)return;
    int mi=MI(q,w),mi1=MI(q,w+1),mx=1;
    if(w<m&&mi==mi1)
    {
        fo(k,2,min(n-q,m-w)+1)if(NIL(q,w,k))mx=k;else break;
    }
    FZ(q,w,mx,mi);
    ss();
}
int main()
{
    int q,w;
    scanf("%d%d",&n,&m);
    ans[1][1]=n*m;
    ss();
    fo(i,1,n)
    {
        fo(j,1,m)printf("%c",a[i][j]+64);
        printf("\n");
    }
    return 0;
}
### 蓝桥杯铺设地砖算法题解题思路 在蓝桥杯竞赛中,“铺设地砖”类题目通常涉及动态规划或组合计数的思想。以下是针对此类问题的一种通用解题思路: #### 动态规划模型构建 对于给定长度 \(N\) 的地面,可以使用不同尺寸的地砖来覆盖整个区域。假设每种地砖的长度分别为 1 和 2,则可以通过定义状态转移方程解决此问题。 令 \(f(n)\) 表示长度为 \(n\) 的地面可以用多少种方式完全铺满。如果最后一块地砖是长度为 1 的地砖,则剩余部分为 \(f(n-1)\),而如果是长度为 2 的地砖,则剩余部分为 \(f(n-2)\)[^1]。因此,状态转移方程可表示如下: \[ f(n) = f(n-1) + f(n-2) \] 边界条件设定为: \[ f(0) = 1 \quad (\text{空地面只有一种情况}) \] \[ f(1) = 1 \quad (\text{仅能放置一块长度为 1 的地砖}) \] 通过上述递推关系,我们可以计算任意长度 \(N\) 下的不同铺设方案数量。 #### 实现代码示例 下面是一个基于以上分析实现的 Java 程序片段用于求解该问题: ```java public class FloorTiling { public static int countWays(int n){ if (n == 0 || n == 1) return 1; int[] dp = new int[n+1]; dp[0]=1;dp[1]=1; for(int i=2;i<=n;i++){ dp[i] = dp[i-1]+dp[i-2]; } return dp[n]; } public static void main(String[] args){ System.out.println(countWays(4)); // 输出应为5 } } ``` #### 结果验证 当输入 \(N=3\) 时,按照上述逻辑得出的结果应该是 3 种可能的方式;而对于更大的数值比如 \(N=10\) 或者其他特定测试数据集中的值,程序同样能够给出正确解答。 另外,在某些变体版本里可能会引入更多类型的瓷砖或者增加额外约束条件(例如颜色搭配规则),这些都需要相应调整基础框架并扩展考虑因素[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值