#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
ll ans = 0;
// Maps for individual edges:
unordered_map<string, ll> cntTop, cntBottom, cntLeft, cntRight;
// Maps for intersections:
// cntLT: for a card’s (left, top) pair
// cntRB: for a card’s (right, bottom) pair
unordered_map<string, ll> cntLT, cntRB;
for (int i = 0; i < N; i++){
string s, t;
cin >> s >> t;
// Decompose the card.
string top = s; // first row
string bottom = t; // second row
string left = "";
left.push_back(s[0]);
left.push_back(t[0]);
string right = "";
right.push_back(s[1]);
right.push_back(t[1]);
// Count potential matches from previously seen cards:
ll horizontal = cntLeft[right] + cntRight[left];
ll vertical = cntTop[bottom] + cntBottom[top];
// A pair is double counted if a previous card has:
// (left, top) equal to (current card's right, current card's bottom)
// or (right, bottom) equal to (current card's left, current card's top).
string key1 = right + bottom;
ll inter1 = cntLT[key1];
string key2 = left + top;
ll inter2 = cntRB[key2];
// The current card contributes (after dividing by 2 to account for order)
ll contr = (horizontal + vertical - inter1 - inter2) / 2;
ans += contr;
// Update maps with the current card.
cntTop[top]++;
cntBottom[bottom]++;
cntLeft[left]++;
cntRight[right]++;
cntLT[left + top]++; // store the (left, top) pair for this card
cntRB[right + bottom]++; // store the (right, bottom) pair for this card
}
cout << ans << "\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |