Оголосимо двовимірний масив , в якому зберігатимемо інформацію про радіоактивне забруднення ділянки. Нехай mas[i][j] = 1, якщо клітинка заражена, і mas[i][j] = 0 в іншому випадку.
Далі перетворимо масив так, щоб mas[i][j] містило кількість радіоактивних клітинок у прямокутнику з кутами та . Це можна зробити за допомогою подвійного циклу по та . Припустимо, що значення mas[x][y] вже перераховані для всіх 1 \le x \le i, 1 \le y \le j, крім mas[i][j]. Тоді виконується наступна формула:
Після цього переберемо всі можливі позиції лівого верхнього кута будинку , де 1 \le i \le m - a + 1, 1 \le j \le n - b + 1, і перевіримо, чи є у відповідному прямокутнику хоча б одна радіоактивна клітинка.
Будинок можна побудувати (тобто вибраний прямокутник не містить радіоактивних клітинок), якщо значення виразу
дорівнює нулю.
Приклад
Розглянемо другий тест. Ліворуч показано вміст масиву після читання вхідних даних, а праворуч – значення елементів цього масиву після перерахунку.
Будинок розміром на можна розмістити лише в одному місці – з лівим верхнім кутом у позиції (i, j) = (3, 2) (нумерація позицій починається з ). Справді, маємо:
Реалізація алгоритму
Оголосимо двовимірний масив . У змінній підраховуватимемо кількість способів розташування будинку.
#define MAX 5001
int mas[MAX][MAX], res;Читаємо вхідні дані.
scanf("%d %d %d %d %d",&m,&n,&a,&b,&k);
memset(mas,0,sizeof(mas));
for (res = i = 0; i < k; i++)
{
scanf("%d %d",&x,&y);
mas[x][y] = 1;
}Перерахуємо елементи масиву так, щоб mas[i][j] містило кількість радіоактивних клітинок у прямокутнику з кутами та .
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
mas[i][j] = mas[i][j] + mas[i-1][j] + mas[i][j-1] - mas[i-1][j-1];Перебираємо всі можливі координати лівого верхнього кута будинку і перевіряємо, чи є хоча б одна радіоактивна клітинка на ділянці, що відповідає будинку. Якщо таких клітинок немає, то в цьому місці можна побудувати будинок. У цьому випадку збільшуємо значення змінної на .
for(i = 1; i <= m - a + 1; i++)
for(j = 1; j <= n - b + 1; j++)
if (mas[i+a-1][j+b-1] + mas[i-1][j-1] – mas[i-1][j+b-1] - mas[i+a-1][j-1] == 0) res++;Виводимо відповідь.
printf("%d\n",res);Реалізація на Java
import java.util.*;
public class Main
{
static int mas[][];
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
int m = con.nextInt();
int n = con.nextInt();
int a = con.nextInt();
int b = con.nextInt();
int k = con.nextInt();
mas = new int[m+1][n+1];
int res = 0;
for(int i = 0; i < k; i++)
{
int x = con.nextInt();
int y = con.nextInt();
mas[x][y] = 1;
}
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
mas[i][j] = mas[i][j] + mas[i-1][j] + mas[i][j-1] - mas[i-1][j-1];
for(int i = 1; i <= m - a + 1; i++)
for(int j = 1; j <= n - b + 1; j++)
if (mas[i+a-1][j+b-1] + mas[i-1][j-1] - mas[i-1][j+b-1] - mas[i+a-1][j-1] == 0) res++;
System.out.println(res);
con.close();
}
}