Problem O
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 14 Accepted Submission(s) : 12
Problem Description
There is a board with 100 * 100 grids as shown below. The left-top gird is denoted as (1, 1) and the right-bottom grid is (100, 100).
We may apply three commands to the board:
In the beginning, all the grids on the board are white. We apply a series of commands to the board. Your task is to write a program to give the numbers of black grids within a required region when a TEST command is applied.
We may apply three commands to the board:
1. WHITE x, y, L // Paint a white square on the board, // the square is defined by left-top grid (x, y) // and right-bottom grid (x+L-1, y+L-1) 2. BLACK x, y, L // Paint a black square on the board, // the square is defined by left-top grid (x, y) // and right-bottom grid (x+L-1, y+L-1) 3. TEST x, y, L // Ask for the number of black grids // in the square (x, y)- (x+L-1, y+L-1)
In the beginning, all the grids on the board are white. We apply a series of commands to the board. Your task is to write a program to give the numbers of black grids within a required region when a TEST command is applied.
Input
The first line of the input is an integer t (1 <= t <= 100), representing the number of commands. In each of the following lines, there is a command. Assume all the commands are legal which means that they won't try to paint/test the grids outside the board.
Output
For each TEST command, print a line with the number of black grids in the required region.
Sample Input
5 BLACK 1 1 2 BLACK 2 2 2 TEST 1 1 3 WHITE 2 1 1 TEST 1 1 3
Sample Output
7 6
题意:
BLACK x y l是指将第x行,y列到第x+l-1行,y+l-1列翻成黑色(初始化时为白色)
WHITE x y l是指将第x行,y列到第x+l-1行,y+l-1列翻成白色(初始化时为白色)
TEST x y l是指求从第x行,y列到第x+l-1行,y+l-1列中白色的有几个
思路:
一开始想的用数状数组,其实这个题目不用树状数组也能过。。。数状数组是更新一个二维区间,查找一个二维区间两个函数,其中更新区间
树状数组代码:
#include <iostream>
#include <cstring>
#define MAX_N 105
using namespace std;
int num[MAX_N + 1][MAX_N + 1];
int color[MAX_N + 1][MAX_N + 1];
int lowbit(int id)
{
return id & (id ^ (id - 1));
}
void modify(int x, int y, int change)
{
int i, j;
int val;
if(color[x][y] == change) return;
if(change == 1) val = 1;
else if(color[x][y] == 1) val = -1;
color[x][y] = change;
if(val == 0) return;
for(i = x; i <= MAX_N; i += lowbit(i))
for(j = y; j <= MAX_N; j += lowbit(j))
num[i][j] += val;
}
int sum(int x, int y)
{
int res = 0, i, j;
for(i = x; i >= 1; i -= lowbit(i))
for(j = y; j >= 1; j -= lowbit(j))
res += num[i][j];
return res;
}
int main()
{
int cn;
char command[10];
int x, y, L, i, r, c;
scanf("%d", &cn);
for(i = 1; i <= cn; i++)
{
scanf("%s%d%d%d", command, &x, &y, &L);
if(strcmp(command, "WHITE") == 0)
{
for(r = x; r < x + L; r++)
for(c = y; c < y + L; c++)
modify(r, c, 0);
}
else if(strcmp(command, "BLACK") == 0)
{
for(r = x; r < x + L; r++)
for(c = y; c < y + L; c++)
modify(r, c, 1);
}
else
{
int count1 = sum(x + L - 1, y + L - 1);
int count2 = sum(x + L - 1, y - 1);
int count3 = sum(x - 1, y + L - 1);
int count4 = sum(x - 1, y - 1);
printf("%d\n", count1 - count2 - count3 + count4);
}
}
return 0;
}
非数状数组代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<cstring>
using namespace std;
int mp[102][102];
void update(int x,int y,int l,char color)
{
int i,j;
for(i=x;i<=x+l-1;i++)
{
for(j=y;j<=y+l-1;j++)
{
if(color=='B')
mp[i][j]=1;
else if(color=='W')
mp[i][j]=0;
}
}
}
int count(int x,int y,int l)
{
int i,j;
int sum=0;
for(i=x;i<=x+l-1;i++)
{
for(j=y;j<=y+l-1;j++)
if(mp[i][j]==1)
sum++;
}
return sum;
}
int main()
{
int T;
int x,y,l;
while(scanf("%d",&T)!=EOF)
{
memset(mp,0,sizeof(mp));
while(T--)
{
char str[6];
cin>>str>>x>>y>>l;
if(str[0]=='B')
{
update(x,y,l,'B');
}
else if(str[0]=='W')
{
update(x,y,l,'W');
}
else if(str[0]=='T')
{
printf("%d\n",count(x,y,l));
}
}
}
return 0;
}