首页 > 其他分享 >问题 C: B001 快乐的蠕虫

问题 C: B001 快乐的蠕虫

时间:2024-12-15 21:01:46浏览次数:5  
标签:B001 struct int 位置 网格 石头 快乐 蠕虫

题目描述

有一只快乐的蠕虫居住在一个m×n大小的网格中。在网格的某些位置放置了k块石头。网格中的每个位置要么是空的,要么放置了一块石头。当蠕虫睡觉时,它在水平方向或垂直方向上躺着,把身体尽可能伸展开来。蠕虫的身躯既不能进入到放有石块的方格中,也不能伸出网格外。而且蠕虫的长度不会短于2个方格的大小。
本题的任务是给定网格,要计算蠕虫可以在多少个不同的位置躺下睡觉。

输入

输入文件的第1行是一个整数t,1<=t<=11,表示测试数据的个数。每个测试数据的第1行为3个整数:m,n和k(0<=m,n,k<=200000),接下来有k行,每行为2个整数,描述了一块石头的位置(行和列,最左上角位置为(1,1))。

输出

对每个测试数据,输出占一行,为一个整数,表示蠕虫可以躺着睡觉的不同位置的数目。

样例输入 复制
1
5 5 6
1 5
2 3
2 4
4 2 
4 3
5 1
样例输出 复制
9

问题分析:

首先要理解题目的意思。题目中有两句话很关键:“当蠕虫睡觉时,它在水平方向或垂直方向上躺着,把身体尽可能伸展开来”,“而且蠕虫的长度不会短于2个方格的大小”。这两句话要结合起来理解。样例输入中的第1个测试数据的网格如图9-1(a)所示,“□”表示空的方格,“■”表示石头。如果只凭第2句话,则仅在第1列,蠕虫就可以在3个位置上躺着,分别是头在(1,1)、(2,1)、(3,1)这3个位置,身躯在垂直方向向上向下伸展开来;但加上第1句话,则这3个位置都是一样的,因为蠕虫在第1列上躺着,它的身躯会尽可能伸展开来,占满第1列所有4个空格。

        对图(a)所示的网格,蠕虫可以在9个位置上躺着,这9个位置分别是:第1列、第2列、第4列、第5列、第1行、第2行、第3行、第4行和第5行。如果把(4,2)这个位置上的石头去掉,则统计出的位置数是10个。因为在第4行(4,3)位置上石头的左边和右边都满足题目的要求。

        本题测试数据中的3个值取值都很大(0<=m,n,k<=200000),如果要把整个网格用二维数组保存起来,内存使用量会超出题目的要求。即使能把整个网格保存起来,扫描这个网格需要用二重循环,时间也会超时。

        本题的处理方法是,在网格的边界处“添加”一些石头,如图9-1(b)所示,“●”表示添加的石头,只需要存储输入的石头位置及添加的石头位置,然后对这些石头的位置进行如下的两种二级排序:

例如,网格中原有的石头,再加上“添加”的石头,一共26个。按第一种方式排序后为:(0,1)、(0,2)、(0,3)、(0,4)、(0,5)、(1,0)、(1,5)、(1,6)、(2,0)、(2,3)、(2,4)、(2,6)、(3,0)、(3,6)、(4,0)、(4,2)、(4,3)、(4,6)、(5,0)、(5,1)、(5,6)、(6,1)、(6,2)、(6,3)、(6,4)、(6,5)。扫描这26个位置,如果前后两个位置x坐标相同,且y坐标相差大于2,则表示其为蠕虫能躺着睡觉的位置。例如(1,0)和(1,5)满足要求,对应到网格中第1行。

AC代码:

#include<stdio.h>
#include<stdlib.h>

struct In
{
    int x;
    int y;
}s[10000000];

int cmpx(const void *a,const void *b)//先比较x再比较y
{
    struct In *c=(struct In *)a;
    struct In *d=(struct In *)b;
    if(c->x!=d->x)
    {
        return c->x-d->x;
    }
    return c->y-d->y;
}
int cmpy(const void*a,const void*b)
{
    struct In*c=(struct In*)a;
    struct In*d=(struct In*)b;
    if(c->y!=d->y)
    {
        return c->y-d->y;
    }
    return c->x-d->x;
}

int main()
{
    int kase,i,m,n,k,j;
    scanf("%d",&kase);
    while(kase--)
    {
        scanf("%d %d %d",&m,&n,&k);
        for(i=0;i<k;i++)
        {
            scanf("%d %d",&s[i].x,&s[i].y);
        }
        for(j=1;j<=n;j++)//左右
        {
            s[i].x=0;
            s[i].y=j;
            i++;
            s[i].x=m+1;
            s[i].y=j;
            i++;
        }
        for(j=1;j<=m;j++)
        {
            s[i].x=j;
            s[i].y=0;
            i++;
            s[i].y=n+1;
            s[i].x=j;
            i++;
        }
        int t=0;
        qsort(s,i,sizeof(s[0]),cmpx);//横躺着的情况
        for(j=0;j<i-1;j++)
        {
            if(s[j].x==s[j+1].x&&s[j+1].y-s[j].y>2)
            {
                  t++;
            }
        }
        qsort(s,i,sizeof(s[0]),cmpy);//竖着躺的情况
        for(j=0;j<i-1;j++)
        {
            if(s[j].y==s[j+1].y&&s[j+1].x-s[j].x>2)
            {
                t++;
            }
        }
        printf("%d\n",t);
    }
    return 0;
}

标签:B001,struct,int,位置,网格,石头,快乐,蠕虫
From: https://blog.csdn.net/sjdhisjwkw/article/details/144460308

相关文章

  • Google Kickstart2022 Round G Problem C 快乐子数组
    有点思路,但还需要细想思路一眼上去,应该是写单调队列,但是不是像写滑动窗口一样写设前缀和为pre,如果一个区间\([l,r]\)满足条件,那么\(pre[l-1]<min(pre[l],pre[l+1],.....,pre[r]\)根据这一点,我们每次枚举到i,只需要统计左端有多少个相对应的j使得pre[j]<pre[i]即可,这时就可以......
  • P4791 [BalticOI 2018] 蠕虫之忧
    [BalticOI2018]蠕虫之忧题目描述题目译自BalticOI2018Day1「WormWorries」本题是一道交互题。在一个三维空间(我们限制大小为N×M......
  • 2024/12/5 【哈希表】202 快乐数
    202.快乐数-力扣(LeetCode)解法1:(1)把数字n转换为字符串,从而得到每一位的数值。事先不知道数字n有多少位。(2)把每一次求平方和得到的数存到集合中,从而避免数字重复导致的循环。classSolution:defcalSquare(self,num):str_n=str(num)sum=0......
  • 《内在小孩快乐你才快乐》有声书视频制作完成
    【内在小孩快乐你才快乐:荷欧波诺波诺是什么】https://www.bilibili.com/video/BV1kPmVYeEX9/?share_source=copy_web&vd_source=20bcb7c5926b4b296dd98bcf9a3c655a【内在小孩快乐你才快乐:序】https://www.bilibili.com/video/BV1CPmVYeEw8/?share_source=copy_web&vd_source=20......
  • 代码随想录:快乐数
    代码随想录:快乐数这题主要是学习一下几种set怎么用。三种set,第一种第二种都是有序的,注意这个序列和插入序列无关,只和插入元素本身有关。第三种哈希表,无序,如果只需要找元素是否出现过,用第三种刚刚好。集合底层实现是否有序数值是否可以重复能否更改数值查询效率增删效......
  • 每日一练:【优先算法】双指针之快乐数(medium)
    1.题目链接:202.快乐数2.题目描述及分析对于一个正整数我们替换为它每个位置上数字的平方和,不断重复这个过程就如上图所示。这里需要补充的是根据鸽巢定理,n个巢穴,n+1个鸽子,,将鸽子都安排进巢穴,那么不管怎么安排,至少有一个有一个巢穴里面鸽数大于1,我们这里取一个超过int......
  • 让编程快乐起来的过程
    熟悉代码片段的添加和编辑,建立自己的代码片段库。掌握常用的shell脚本编写能力,能够快速的编写文件处理相关的插件。便于构建各种模板文件并生成对应的快捷取用命令。熟练使用vim和双拼,你越熟悉它们,你就会越自由。掌握vim宏功能和脚本功能。便于批量处理重复性的修改和生......
  • 快乐数(c语言)
    1.「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为1,也可能是无限循环但始终变不到1。如果这个过程结果为1,那么这个数就是快乐数。如果n是快乐数就返回true;不是,则返回false。1<=n<=2^31 -1......
  • 快乐数学1培养数学直觉
    1培养数学直觉我们最初接触一个概念时,会形成我们的直觉。而我们的直觉会影响我们对一门学科的喜爱程度。什么意思呢?假设我们想给“猫”下一个定义:古代的定义:一种毛茸茸的动物,有爪子、牙齿、尾巴和四条腿,高兴时发出咕噜声,生气时发出嘶嘶声。进化定义:某一物种(猫科动物)的......
  • 国庆快乐!
    谨以此代码庆祝国庆~!!前排提示,代码并不严谨!请勿随意传播!请勿恶意解读!!index.html文件:<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-sca......