E - Stones
-
from collections import deque from typing import List # If you want to use a deep recursion, you need to increase the recursion limit # Python's default recursion limit is 1000 # Uncomment the following two lines if you need to use deep recursion # import sys # sys.setrecursionlimit(10**8) class Solution: @staticmethod def solve(n: int, positions: List[tuple[int, int]]) -> int: """ Args: n (int): number of stones positions (list[tuple[int,int]]): an array consisting n tuple of integers where the tuple at i-th index represents the xy-coordinate of the i-th stone (The first (resp. second) integer in the pair is the x-coordinate (resp. y-coordinate)) Returns: int: an integer represent the maximum number of stones that can be removed """ xmap = {} ymap = {} id = 0 for x, y in positions: if xmap.get(x) is None: xmap[x] = [] if ymap.get(y) is None: ymap[y] = [] xmap[x].append(id) ymap[y].append(id) id += 1 graph = [[] for _ in range(n)] for k in xmap.keys(): for i in range(1, len(xmap[k])): u = xmap[k][i - 1] v = xmap[k][i] graph[u].append(v) graph[v].append(u) for k in ymap.keys(): for i in range(1, len(ymap[k])): u = ymap[k][i - 1] v = ymap[k][i] graph[u].append(v) graph[v].append(u) ans = 0 visited = [0 for i in range(n)] for i in range(n): if visited[i] == 1: continue ans += 1 q = deque() q.append(i) while len(q) != 0: u = q.popleft() if visited[u] == 1: continue visited[u] = 1 for v in graph[u]: if visited[v] == 1: continue q.append(v) return n - ans if __name__ == "__main__": n = int(input()) positions = [tuple(map(int, input().split())) for i in range(n)] solution = Solution.solve(n, positions) print(solution)
-
#include <iostream> #include <unordered_map> #include <vector> using namespace std; class Solution { public: /** * @param n: number of stones * @param positions: an array consisting n pair of integers where the pair at * i-th index represents the xy-coordinate of the i-th stone (The first (resp. * second) integer in the pair is the x-coordinate (resp. y-coordinate)) * @return: return an integer represent the maximum number of stones that can * be removed */ static int solve(int n, std::vector<std::pair<int, int> >& positions) { // Implement your solution by completing the following function unordered_map<int, vector<int> > row2stones; unordered_map<int, vector<int> > col2stones; vector<pair<int, int> > stones; cin >> n; for (int i = 0; i < n; i++) { int x, y; cin >> x >> y; stones.emplace_back(x, y); if (row2stones.find(x) == row2stones.end()) row2stones[x] = vector<int>(); if (col2stones.find(y) == col2stones.end()) col2stones[y] = vector<int>(); row2stones[x].emplace_back(i); col2stones[y].emplace_back(i); } vector<vector<int> > adjlist(n); for (auto& [row, vec] : row2stones) { for (int i = 1; i < vec.size(); i++) { adjlist[vec[i]].emplace_back(vec[i - 1]); adjlist[vec[i - 1]].emplace_back(vec[i]); } } for (auto& [col, vec] : col2stones) { for (int i = 1; i < vec.size(); i++) { adjlist[vec[i]].emplace_back(vec[i - 1]); adjlist[vec[i - 1]].emplace_back(vec[i]); } } vector<int> visited(n, 0); int ncc = 0; for (int i = 0; i < n; i++) { if (visited[i]) continue; ncc++; queue<int> q; q.emplace(i); while (!q.empty()) { int u = q.front(); q.pop(); if (visited[u]) continue; visited[u] = 1; for (int v : adjlist[u]) { if (visited[v]) continue; q.emplace(v); } } } return n - ncc; } }; int main() { int n; std::cin >> n; std::vector<std::pair<int, int> > positions(n); for (int i = 0; i < n; ++i) { int x, y; std::cin >> x >> y; positions[i] = {x, y}; } int ans = Solution::solve(n, positions); std::cout << ans << "\n"; return 0; }
-
import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; class Solution { /** * @param n: number of stones * @param x: an array consisting n integers where the i-th integer represents the x-coordinate of * the i-th stone * @param y: an array consisting n integers where the i-th integer represents the y-coordinate of * the i-th stone * @return: return an integer represent the maximum number of stones that can be removed */ static int solve(int n, int[] X, int[] Y) { // Implement your solution here HashMap<Integer, ArrayList<Integer> > xmap = new HashMap<>(); HashMap<Integer, ArrayList<Integer> > ymap = new HashMap<>(); for (int i = 0; i < n; i++) { if (!xmap.containsKey(X[i])) xmap.put(X[i], new ArrayList<>()); if (!ymap.containsKey(Y[i])) ymap.put(Y[i], new ArrayList<>()); xmap.get(X[i]).add(i); ymap.get(Y[i]).add(i); } ArrayList<ArrayList<Integer> > adjList = new ArrayList<>(n); for (int i = 0; i < n; i++) adjList.add(new ArrayList<Integer>()); for (int k : xmap.keySet()) { for (int i = 1; i < xmap.get(k).size(); i++) { int u = xmap.get(k).get(i - 1); int v = xmap.get(k).get(i); adjList.get(u).add(v); adjList.get(v).add(u); } } for (int k : ymap.keySet()) { for (int i = 1; i < ymap.get(k).size(); i++) { int u = ymap.get(k).get(i - 1); int v = ymap.get(k).get(i); adjList.get(u).add(v); adjList.get(v).add(u); } } int[] visited = new int[n]; for (int i = 0; i < n; i++) visited[i] = 0; int ans = 0; for (int i = 0; i < n; i++) { if (visited[i] != 0) continue; ans += 1; Queue<Integer> q = new LinkedList<Integer>(); q.add(i); visited[i] = 1; while (q.size() != 0) { int u = q.peek(); q.remove(); for (int id : adjList.get(u)) { if (visited[id] == 1) continue; visited[id] = 1; q.add(id); } } } return n - ans; } public static void main(String[] args) throws java.lang.Exception { Scanner input = new Scanner(System.in); int n = input.nextInt(); int[] x = new int[n]; int[] y = new int[n]; for (int i = 0; i < n; i++) { x[i] = input.nextInt(); y[i] = input.nextInt(); } int ans = solve(n, x, y); System.out.println(ans); input.close(); } }