baekjoon

[백준] 11670 초등 수학

윤만석 2023. 6. 26. 19:35

문제

엘렌은 학생들에게 초등 수학을 가르치고 있고 곧 기말고사를 앞두고 있다. 기말고사는 n개의 질문들로 이루어져 있다.
각 질문마다 학생들은 한 쌍의 숫자들을 더하거나(+), 빼거나(-) 혹은 곱해야한다(*).

엘렌은 이미 n개의 숫자 쌍들을 골라놨다. 남은것은 이제 각 쌍의 숫자마다 어떠한 연산을 수행해야 할지 결정하는 것이었다.

학생들이 지루하지 않게 하기위해 엘렌은 n개의 연산결과들이 모두 다르게 하고 싶어했다.

엘렌이 시험을 잘 준비 할 수 있게 도와주자.

입력

첫째 줄에 순서쌍의 개수 n (1 ≤ n ≤ 2 500)이 입력된다.

다음 n개의 줄에 걸쳐서 순서쌍 a,b (−106 ≤ a, b ≤ 106)가 입력된다.

출력

입력과 같은 순서대로 (a,b) 순서쌍이 유효한 방정식과 함께 출력된다. 각각의 방정식은 5개의 요소로 나뉜다.
a와 3개의 연산자(+ 혹은 - 혹은  *)중 하나, b 그리고 = 와 연산결과이다. 모든 연산결과는 달라야한다.

만약 출력 할 수 있는 답이 여러개라면 아무거나 출력하고, 답이 없다면 “impossible” 을 출력한다.

 

이분 매칭 문제입니다.

이 문제에서 까다로웠던 점은 반대쪽 매칭 정점의 범위가 -10^6~10^6까지라는 점입니다.

따라서,,, 만들 수 있는 정점의 리스트를 작성하고 중복제거를 해준뒤에 인덱싱처리를 따로 해주어야합니다.

개수는 3*2500=7500이므로 가능합니다

#include<bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
#define mset(v) memset(v,0,sizeof(v))
#define IDX(v, x) lower_bound(v.begin(),v.end(), x) - v.begin()
#define rep(i,a) for(int i=0;i<a;++i)
#define REP(i,a) for(int i=1;i<=a;++i)

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int>ti;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
int dy[] = { -1,0,1,0 }, dx[] = { 0,1,0,-1 }, INF = 987654321;
ll N, a, b, cnt, v[8501], s[8501], d[8500];
vector<ll> nums;
pair<ll, ll> num[2526];
vector<ll> adj[2526];
bool dfs(int k) {
	if (v[k])return false;
	v[k] = 1;
	for (int r : adj[k]) {
		
		if (s[r] == -1 || dfs(s[r])) {
			s[r] = k;
			d[k] = r;
			return true;
		}
	}
	return false;
}
int main() {
	FAST;
	cin >> N;
	REP(i, N) {
		cin >> a >> b;
		num[i] = { a,b };
		nums.push_back(a + b);
		nums.push_back(a - b);
		nums.push_back(a * b);

	}
	sort(nums.begin(), nums.end());
	nums.erase(unique(nums.begin(), nums.end()), nums.end());
	memset(s, -1, sizeof(s));
	REP(k, N) {
		auto [x, y] = num[k];
		adj[k].push_back(IDX(nums, x + y));
		adj[k].push_back(IDX(nums, x - y));
		adj[k].push_back(IDX(nums, x * y));

		mset(v);
		if (!dfs(k)) {
			cout << "impossible";
			return 0;
		}
	}
	REP(i, N) {
		auto [x, y] = num[i];
		ll target = nums[d[i]];

		if (x + y == target) {
			cout << x << " + " << y << " = " << target << "\n";
		}
		else if (x - y == target) {
			cout << x << " - " << y << " = " << target << "\n";
		}
		else if (x * y == target) {
			cout << x << " * " << y << " = " << target << "\n";
		}
	}

}