首页 > 其他分享 >洛谷题单指南-递推与递归-P1228 地毯填补问题

洛谷题单指南-递推与递归-P1228 地毯填补问题

时间:2024-02-21 17:46:55浏览次数:27  
标签:int 洛谷题 区域 && y1 x1 递推 公主 P1228

原题链接:https://www.luogu.com.cn/problem/P1228

题意解读:用4种毯子铺满2^k * 2^k的区域,留出一个公主位置,输出所有毯子拐角的坐标以及哪种毯子,看起来有点无从下手,

可以从k=1,k=2,k=3入手去依次考虑,找到规律,用分治法解决。

解题思路:

1、当k=1时,即2*2的区域,对于任意一个位置是公主,都可以得到唯一一种铺设方案

2、当k=2时,即4*4的区域,对于任意一个位置是公主,如下图:

可以将4*4区域划分成4个2*2的区域

如果每个区域都有一个公主,问题就好解决了,因为右上区域有了公主,可以假设最中间的2*2区域的右上角有公主,先对这个区域进行铺设:

然后,把中间铺设的地毯都当做公主,这样就能保证4个2*2的区域都有了公主:

再分4个区域依次进行处理,问题就变成了k=1时的情况,即可得到上图的结果。

3、同理,当k=3时,即8*8的区域,对于任意位置是公主,如下图:

将8*8区域划分成4个4*4区域

根据公主所在的区域,对中间2*2区域进行铺设

这样,假设中间2*2铺设的毯子都是公主,则4个4*4区域就都有了公主

再依次对4个4*4区域进行处理,问题就变成了k=2时的情况,最终可以变成k=1时的情况,问题得解。

100分代码:

#include <bits/stdc++.h>
using namespace std;

int k, x, y;

//cover是铺地毯函数,(x1,y1)是左上角的坐标,(x2,y2)是右下角的坐标,(x,y)是公主的的坐标
void cover(int x1, int y1, int x2, int y2, int x, int y)
{
    if(x2 - x1 == 1) //2 * 2区域时
    { 
        //公主在左上角,用毯子1
        if(x1 == x && y1 == y) cout << x2 << " " << y2 << " " << 1 << endl; 
        //公主在右上角,用毯子2
        else if(x1 == x && y2 == y) cout << x2 << " " << y1 << " " << 2 << endl;
        //公主在左下角,用毯子3
        else if(x2 == x && y1 == y) cout << x1 << " " << y2 << " " << 3 << endl;
        //公主在右下角,用毯子4
        else cout << x1 << " " << y1 << " " << 4 << endl;

        return;
    }

    //将2^k * 2^k区域分成4个2^(k-1) * 2^(k-1)的区域
    //计算公主在哪个区域,把正中间的2*2区域用一个地毯覆盖,这个地毯相当于让4个2^(k-1) * 2^(k-1)的区域都有一个公主
    //再递归处理

    int len = x2 - x1 + 1; //len是边长
    int half = len / 2; //half是边长的一半

    //中间2 * 2区域每个格子的坐标
    int xa = x1 + half - 1, ya = y1 + half - 1; //左上
    int xb = x1 + half - 1, yb = y1 + half; //右上
    int xc = x1 + half, yc = y1 + half - 1; //左下
    int xd = x1 + half, yd = y1 + half; //右下

    //公主在左上区域
    if(x >= x1 && x <= xa && y >= y1 && y <= ya) 
    {
        //填补正中间2*2区域
        cover(xa, ya, xd, yd, xa, ya);
        //设定左上区域的公主位置
        xa = x, ya = y;
    }
    //公主在右上区域
    else if(x >= x1 && x <= xb && y >= yb && y <= y2)
    {
        //填补正中间2*2区域
        cover(xa, ya, xd, yd, xb, yb);
        //设定右上区域的公主位置
        xb = x, yb = y;
    }
    //公主在左下区域
    else if(x >= xc && x <= x2 && y >= y1 && y <= yc)
    {
        //填补正中间2*2区域
        cover(xa, ya, xd, yd, xc, yc);
        //设定左下区域的公主位置
        xc = x, yc = y;
    }
    //公主在右下区域
    else 
    {
        //填补正中间2*2区域
        cover(xa, ya, xd, yd, xd, yd);
        //设定右下区域的公主位置
        xd = x, yd = y;
    }

    //递归处理4个2^(k-1) * 2^(k-1)的区域
    cover(x1, y1, x1 + half - 1, y1 + half - 1, xa, ya); //左上
    cover(x1, y1 + half, x1 + half - 1, y2, xb, yb);  //右上
    cover(x1 + half, y1, x2, y1 + half - 1, xc, yc);  //左下
    cover(x1 + half, y1 + half, x2, y2, xd, yd); //右下
}

int main()
{
    cin >> k >> x >> y;
    cover(1, 1, 1 << k, 1 << k, x, y);
    return 0;
}

 

标签:int,洛谷题,区域,&&,y1,x1,递推,公主,P1228
From: https://www.cnblogs.com/jcwy/p/18025829

相关文章

  • 洛谷题单指南-递推与递归-P1010 [NOIP1998 普及组] 幂次方
    原题链接:https://www.luogu.com.cn/problem/P1010题意解读:输出一个正整数的2的幂次方表示,需要用到二进制数学知识,将整数拆解成2的次幂之和,幂次方也要进行拆解,因此容易想到通过递归处理。解题思路:先看样例,给定整数137,要拆解成2的幂次方之和,先考虑i使得刚好137>=2^i时,i取7,因此2......
  • 洛谷题单指南-递推与递归-P1259 黑白棋子的移动
    原题链接:https://www.luogu.com.cn/problem/P1259题意解读:要打印最终的状态,关键在找到一些变化的规律,直接的暴力搜索复杂度太高。解题思路:从样例出发ooooooo*******--oooooo--******o*oooooo******--o*ooooo--*****o*o*ooooo*****--o*o*oooo--****o*o*o*oooo****--o*o*o*ooo--......
  • 洛谷题单指南-递推与递归-P3612 [USACO17JAN] Secret Cow Code S
    原题链接:https://www.luogu.com.cn/problem/P3612题意解读:字符串加长的时候,是先把最后一个字符接上,再拼接其余字符,注意不是翻转,要找第n个字符,就要看字符串加长几次后长度能超过n,然后在加长后的字符串中找第n个字符。解题思路:如果直接通过模拟法,字符串长度太长,且要找的第n个数......
  • 洛谷题单指南-递推与递归-P1990 覆盖墙壁
    原题链接:https://www.luogu.com.cn/problem/P1990题意解读:用两种可旋转的形状铺满N*2的区域,求方案数,可以使用递推。解题思路:步骤1、设f[i]表示铺满i*2的区域的方案数根据要求,i*2区域最后一列有4种可能的铺法:如果采用图1铺法,则有f[i]=f[i-1]如果采用图2铺法,则有f[i]=f......
  • 洛谷题单指南-递推与递归-P1164 小A点菜
    原题链接:https://www.luogu.com.cn/problem/P1164题意解读:要求正好把钱花完,并且统计不同的点菜方案数,本质上是一个背包问题,给定背包体积,要求物品正好装满背包的方案数。解题思路:1、最直观的解法是暴搜:DFS枚举每一道菜,有点或者不点两种选择,并且累加上已花费的总金额递归前,判断......
  • 洛谷题单指南-递推与递归-P2437 蜜蜂路线
    原题链接:https://www.luogu.com.cn/problem/P2437题意解读:根据题目要求,只能从标号小的蜂房爬到标号大的相邻蜂房,即每次要么爬到+1的蜂房,要么爬到+2的蜂房,本质上是一个斐波那契数列问题,和数楼梯问题一样。解题思路:要求从m号蜂房到n号蜂房的路径,即走n-m级楼梯的方案,n最大1000,同样......
  • 洛谷题单指南-递推与递归-P1928 外星密码
    原题链接:https://www.luogu.com.cn/problem/P1928题意解读:要对形如xxx[Nxxx]xxx的字符串进行解码,[]内第一个数表示括号中字符串重复的次数,可以嵌套。解题思路:用递归进行处理,设函数decode(start,end)将下标从start到end之间字符串进行解码递归过程如下:遍历start~end的每一个字......
  • Codeforces Round 113 (Div. 2)E. Tetrahedron(dp、递推)
    目录题面链接题意题解代码总结题面链接E.Tetrahedron题意从一个顶点出发走过路径长度为n回到出发点的方案总数题解考虑dp\(f[i][0|1|2|3]\):走了i步,现在在j点的方案总数转移:\(f[i][0]=f[i-1][1]+f[i-1][2]+f[i-1][3]\)\(f[i][1]=f[i-1][0]+f[i-1][2]+f[i-1][3]\)\(f......
  • 洛谷题单指南-递推与递归-P1464 Function
    原题链接:https://www.luogu.com.cn/problem/P1464题意解读:虽然a、b、c可输入的范围比较大,但是递归中,只会限制在0-20以内,由于递归中有大量的重复计算,因此需要采用记忆化搜索来保存已经计算过的递归函数值。解题思路:定义三位数组LLmem[25][25][25],mem[a][b][c]保存w(a,b,c)的......
  • 洛谷题单指南-递推与递归-P1028 [NOIP2001 普及组] 数的计算
    原题链接:https://www.luogu.com.cn/problem/P1028题意解读:给定n,构造数列,可以用递归或者递推。解题思路:1、递归定义count(n)返回数列的个数  n==1时,count(n)=1  n!=1时,count(n)=1+count(1)+count(2)+...+count(n/2)注意,递归会导致大量重复计算,需要用一个hash......