2549. 删除他们! 解题报告

2549. 删除他们!


【问题背景】

Sombra 在很小的时候就表现出了对于电脑的天份。
八个月大的时候,她就能自己爬着过去打开电脑。
四岁的时候就能够正常的使用电脑————多数人的那种正常,打字,翻网页什么的。
六岁的时候,她已经开始学习编程了,之后也参加了一些编程比赛。
八岁,在算法领域玩耍了两年的她,转向了实际应用的领域。
这时,“黑客”这个职业进入了她的视野。

不过这次我们要讲的是 Sombra 小时候的事。
三岁的时候, Sombra 的妈妈教她用电脑。
“Sombra,今天我教你删除文件。”
“这个文件夹中有很多文件,我每次可以框选一些文件,然后按下 Del 键,这样它们就被扔到回收站里去了。”
说着,Sombra 妈妈框选了一些文件,删掉了它们,后面的文件向前补了上来。
“我每次在文件夹里框一下,然后删掉它选中的文件,最后,你告诉我还剩了多少个文件好吗?”

【问题描述】

给一个有 N 行,M 列的文件夹,每个位置上原本都有一个文件。
(行编号从上到下递增,列编号从左到右递增,从 0 开始使用)
Sombra 的妈妈一共会框选并删除 Q 次,
每次用 4 个坐标表示,X1,Y1,X2,Y2,表示框选从第 X1 行,Y1 列开始,一直到第 X2 行,Y2 列,包含边界上的文件。

最后请回答,还剩多少个文件没有被删除。

【输入格式】

输入共 Q+1 行。

第 1 行包含 3 个正整数,N,M,Q,含义如上所述。
第 1 +(1) 至 1 +(Q) 行,每行包含 4 个非负的整数,X1,Y1,X2,Y2,含义如上所述。

【输出格式】

输出共 1 行。

第 1 行包含 1 个非负的整数,表示最后剩余的文件数目。

【样例输入】

2 3 2
0 1 0 2
0 2 1 2

【样例输出】

3

【数据规模与约定】

对于测试点 1 到 3,N <= 10; M <= 10; Q <= 5
对于测试点 4 到 10,Q <= 100

对于全部数据,保证 N*M <= 1,000,000; 0 <= X1 <= X2 < N; 0 <= Y1 <= Y2 < M; Q <= 100

全部数据中的X1,Y1,X2,Y2均为在其合法范围内随机先选出的。

【更多说明】

文件向前补齐规则:
如果文件本行前一列位置处为空,则补到前一列
如果文件位于某行第一个,前一行最后一列位置处为空,则补到前一行末尾 如此循环,直至不能再补为止
(与 Windows 系统的文件夹中删除文件后向前补齐的规则相同)




解题思路该题删除文件时可以看成直接从后面删,因为删掉的文件还会有后续补上相当于从后删(x2-x1)*(y2-y1)个;所以可以先扫一下x1,x2,y1,y2范围内有多少文件,就从后面删几个文件,div一下再mod一下就行了。但要注意上一次未删完的文件个数,本次应先将mod所得与未删完个数比较,若mod大于未删完个数,将div++,mod=mod-未删完个数再操作。



思路就是这样的,再观察数据,100%的数据是N*M<=1,000,000;可能有人不会搞二维数组的MAXM,MAXN,因为开小会T,开大会M,就是A不了。因此,我们应该记住,看到m*n的数据范围,很多时候应该用一维数组来模拟二维数组,相当于开散列。



代码如下:

#include <cstdio>
using namespace std;
bool mp[1000003];
int N, M, Q;
int S;
void work() {
    int X1, Y1, X2, Y2;
    scanf("%d %d %d %d", &X1, &Y1, &X2, &Y2);
    for (int i = X1; i <= X2; i++)
        for (int j = Y1; j <= Y2; j++)
            mp[i*M+j] = true;
    int lt = 0;
    for (int i = 0; i < S; i++)
        if (!mp[i])
            mp[lt++] = false;
    S = lt;
}
int main() {
    freopen("deleteit.in", "r", stdin);
    freopen("deleteit.out", "w", stdout);
    scanf("%d %d %d", &N, &M, &Q);
    S = N*M;
    for (int i = 0; i < Q; i++)
        work();
    printf("%d\n", S);
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值