c++algorithmc++17chess

(Contest problem) Count the number of squares that are not attacked by bishops


My solution is in below.

The bishop in chess is a piece that attacks all squares on the same diagonal (on both diagonals).

Picture

Shakhriyar placed m bishops on a chessboard of size n * n. Now he wants to count the number of squares that are not attacked by bishops. Help Shahriyar in this matter.

Input data First line contains two integers: the size n (1 ≤ n ≤ 10^6) of a chessboard and the number of bishops m (1 ≤ m ≤ 10^5). Each of the next m lines contains pair of integers: r[i] и c[i] (1 ≤ r[i], c[i] ≤ n) - the numbers of row and column where the bishop number i is located. The bishops are numbered from 1 to m. All bishops are located on different squares.

Output data Print the number of squares not attacked by the bishops.

https://www.eolymp.com/en/problems/9630

Input example #1

10 6

4 7

8 5

8 7

6 2

9 7

8 4

Output example #1

33

I solved up to here:

(sorry for the messy picture)

Picture 1 Picture 2

diagonals=2n-1

d-diagonals number

(i;j)-coordinats of points(y,x)

From picture 1:

1:(6;1)

2:(5;1); (6;2)

3:(4;1); (5;2); (6;3)

4:(3;1); (4;2); (5;3); (6;4)

...

10:(1;5); (2;6)

11:(1;6)

d=n-(i-j);

From picture 2:

1:(1;1)

2:(1;2); (2;1)

3:(1;3); (3;1); (2;2)

4:(1;4) (4;1) (2;3) (3;2)

...

d=i+j-1;

Intersections of diagonals:

Diagonals from picture 1(2) Diagonals from picture 2(1)
1, 11 6
2, 10 5, 6, 7
3, 9 4,5,6,7,8
4, 8 3,4,5,6,7,8,9
5, 7 2,3,4,5,6,7,8,9,10
6 1,2,3,4,5,6,7,8,9,10,11

While finding the number of points, Intersections are preventing me . How can I fix this?

My code(C++):

#include<iostream>
#include<set>
using namespace std;
int main(){
    set<int> hit_diagonals1,hit_diagonals2;
    int n,m;
    cin>>n>>m;
    for(int k=0,i,j; k<m; k++){///O(m)-->1e5
        cin>>i>>j;
        hit_diagonals1.insert(n-(i-j));
        hit_diagonals2.insert(i+j-1);
    }
    int cnt=0;//hit_points_number
    
    //.....
    
    cout<<n*n-cnt<<'\n';
    return 0;
}


Solution

  • You can solve this in O(m log m) time using a diagonal sweep-line algorithm.

    First, let's call the diagonals where x+y is constant the "backslash diagonals" and the "slash" diagonals will be the ones where x-y is constant.

    Now we can consider the backslash diagonals in order from 0 to 2m+1 (the maximum x+y).

    First, make a list of "events". For each bishop position (x,y), record:

    Make an initially empty dictionary slashes to keep track of the number of bishops covering each slash diagonal. While modifying this map, you will also make sure that you can keep track of the number of non-zero entries.

    Now, sort the events by backslash diagonal, and process them in order, grouping by backslash diagonal.

    For each backslash group <= (m-1)+(m-1):

    Finally, if you didn't process backslash 2(m-1), the last one, then use the add the number of squares in all the unprocessed backslashes -- they aren't attacked.

    Note that the constraints in the problems suggest that an O(m2), O(m + n), or O(m + n log n) algorithm is expected. This is O(m log m), which is then better than they expect.