题目描述
Farmer John 的草地可以被看作是一个由正方形方格组成的巨大的二维方阵(想象一个巨大的棋盘)。初始时,草地上是空的。
Farmer John 将会逐一地将 N(1≤N≤10^5)头奶牛加入到草地上。第 i 头奶牛将会占据方格 (xi,yi),不同于所有已经被其他奶牛占据的方格(0≤xi,yi≤1000)。
一头奶牛被称为是「舒适的」,如果它水平或竖直方向上与恰好三头其他奶牛相邻。Farmer John 对他的农场上舒适的奶牛数量感兴趣。对 1…N中的每一个 i,输出第 i 头奶牛加入到草地上之后舒适的奶牛的数量。
输入格式(从终端 / 标准输入读入):
输入的第一行包含一个整数 N。以下 N 行每行包含两个空格分隔的整数,表示一头奶牛所在的方格坐标 (x,y)。输入保证所有方格的坐标是不同的。
输出格式(输出至终端 / 标准输出):
输出的第 i 行包含前 i 头奶牛加入到草地上之后舒适的奶牛的数量。
输入样例:
8 0 1 1 0 1 1 1 2 2 1 2 2 3 1 3 2
输出样例:
0 0 0 1 0 0 1 2
样例解释
在前四头奶牛加入之后,位于 (1,1)(1,1) 的奶牛是舒适的。
在前七头奶牛加入之后,位于 (2,1)(2,1) 的奶牛是舒适的。
在前八头奶牛加入之后,位于 (2,1)(2,1) 和 (2,2)(2,2) 的奶牛是舒适的。
测试点性质:
- 测试点 1-4 满足N≤400。
- 测试点 5-12 没有额外限制。
供题:Benjamin Qi
要求及思路:
1. 要求:给出n头奶牛的坐标位置,计算前i头奶牛中有多少头奶牛满足舒适的条件,舒适即为上下左右4个相邻点中有且仅有3个位置有牛。
2. 思路:n为10^5,如果加入一头牛,然后再去完整的遍历之前的所有牛是否是舒适的,这样会超时。但是好在,一个新的点的加入,只会影响其上下左右四个点牛是否会改变状态,因此我们可以记录之前舒适牛的头数,在此基础上验证和更新5个位置的状态就好。
3. 状态改变只有两种,要么原来是舒适,加入之后不舒适了,要么原来是不舒适,加入之后就舒适了。所以,找到第i头牛的上下左右四个位置,判断加入之后的状态,再加入第i个点,判断之后的状态,如果不一致,则考虑是++还是--。
知识点:
模拟、贪心、二维数组、嵌套循环、条件
程序:
#include <iostream>
#include <cstdio>
using namespace std;
bool map[1005][1005];
int dxy[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
//检查x,y周围四个方向上是否恰好有3个点
bool check(int x, int y){
if (map[x][y] == 0)return 0;
int point = 0;
for (int i = 0; i < 4; i++){
//注意判断越界
if (map[x + dxy[i][0]][y + dxy[i][1]] && x + dxy[i][0] >= 0 && x + dxy[i][0] <= 1000 && y + dxy[i][1] >= 0 && y + dxy[i][1] <= 1000){
point++;
}
}
return point == 3;
}
int main(){
int n;
cin >> n;
int ans = 0;
for (int i = 1; i <= n; i++){
int x, y;
cin >> x >> y;
//新点加入之前,check该点周围四个点是否有舒适点
for(int j = 0; j < 4; j++) {
//原来就是舒适点
if (check(x + dxy[j][0], y + dxy[j][1])){
//看新加入xy点后是否仍为舒适点
map[x][y] = 1;
//如果是,则不需要为总和新增,更新xy点为0看下一个点
if(check(x + dxy[j][0], y + dxy[j][1])) {
map[x][y] = 0;
}else {//如果不是了,就在总和更新减少,同时更新xy点
ans--;
map[x][y] = 0;
}
}else {//原来不是舒适点
//看新加入xy点后是否变为舒适点
map[x][y] = 1;
//如果是,则总和新增1,更新xy点为0看下一个点
if(check(x + dxy[j][0], y + dxy[j][1])) {
ans++;
map[x][y] = 0;
}else {//如果仍然不是,则无需变化,同时更新xy点
map[x][y] = 0;
}
}
}
//加入该点
map[x][y] = 1;
if (check(x, y))ans++;
cout << ans << endl;
}
return 0;
}
思考:
1. 题意比较容易忽略,相邻这个词,意味着只有上下左右四个点,其余位置不算
2. 题意还比较容易忽略恰好这个词,读题太重要了~
3. 注意判断越界以及加入第i头牛的舒适状态