Ev#764

Ev (Həll təhlili)

İki ölçülü massivi elan edək, burada sahənin radioaktiv çirklənməsi haqqında məlumatı saxlayacağıq. Tutaq ki, mas[i][j] = 1, əgər xanası çirklənibsə, və mas[i][j] = 0 əks halda.

Sonra massivini elə çevirək ki, mas[i][j] və künclü düzbucaqlıdakı radioaktiv xanaların sayını saxlasın. Bunu və üzrə ikiqat dövrə ilə etmək olar. Tutaq ki, mas[x][y] dəyərləri mas[i][j] istisna olmaqla bütün 1 \le x \le i, 1 \le y \le j üçün artıq yenidən hesablanıb. Onda aşağıdakı düstur doğrudur:

mas[i][j] = mas[i][j] + mas[i – 1][j] + mas[i][j - 1] - mas[i - 1][j - 1]

Bundan sonra evin sol yuxarı küncünün bütün mümkün mövqelərini , burada 1 \le i \le m - a + 1, 1 \le j \le n - b + 1, sıralayacağıq və müvafiq düzbucaqlıda heç olmasa bir radioaktiv xananın olub-olmadığını yoxlayacağıq.

Ev tikmək olar (yəni seçilmiş düzbucaqlı radioaktiv xanalar ehtiva etmir), əgər

mas[i + a - 1][j + b - 1] + mas[i - 1][j - 1] - mas[i - 1][j + b - 1] - mas[i + a - 1][j - 1]

ifadəsinin dəyəri sıfıra bərabərdirsə.

Nümunə

İkinci testi nəzərdən keçirək. Solda giriş məlumatları oxunduqdan sonra massivinin məzmunu, sağda isə yenidən hesablamadan sonra bu massivin elementlərinin dəyərləri göstərilmişdir.

-yə ölçülü ev yalnız bir yerdə yerləşdirilə bilər – sol yuxarı künc (i, j) = (3, 2) mövqeyində (mövqelərin nömrələnməsi -dən başlayır). Həqiqətən də:

mas[4][3] + mas[2][1] - mas[4][1] - mas[2][3] = 4 + 1 - 2 - 3 = 0

Alqoritmin reallaşdırılması

İki ölçülü massivi elan edək. dəyişənində evin yerləşdirilməsinin mümkün üsullarının sayını hesablayacağıq.

#define MAX 5001
int mas[MAX][MAX], res;

Giriş məlumatlarını oxuyuruq.

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;
}

Massivin elementlərini elə yenidən hesablayaq ki, mas[i][j] və künclü düzbucaqlıdakı radioaktiv xanaların sayını saxlasın.

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];

Evin sol yuxarı küncünün bütün mümkün koordinatlarını sıralayırıq və evə uyğun sahədə heç olmasa bir radioaktiv xananın olub-olmadığını yoxlayırıq. Əgər belə xanalar yoxdursa, o zaman bu yerdə ev tikmək olar. Bu halda dəyişəninin dəyərini artırırıq.

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++;

Cavabı çıxarırıq.

printf("%d\n",res);

Java reallaşdırması

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();
  }
}