[백준/BOJ] 백준 12757번 : 전설의 JBNU

2021. 2. 18. 23:11알고리즘 문제풀이

www.acmicpc.net/problem/12757

 

12757번: 전설의 JBNU

첫 줄에는 초기 데이터의 개수인 \(N(1 \le N \le 100,000)\) 과 명령 횟수인 \(M(1 \le M \le 100,000)\), 가장 근접한 Key까지의 거리의 제한인 \(K(1 \le K \le 10,000)\)가 주어진다.  입력의 둘째 줄부터 N개의 줄에

www.acmicpc.net

map<int, int> db을 통해 데이터베이스를 표현하고, lower_bound와 upper_bound를 통해 문제를 해결했다.

 

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

int n, m, k;
map<int, int> db;
map<int, int>::iterator it1;
map<int, int>::iterator it2;

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> k;

	for (int i = 0; i < n; i++)
	{
		int key, value;
		cin >> key >> value;

		db.insert(make_pair(key, value));
	}

	for (int i = 0; i < m; i++)
	{
		int order;
		int key, value;
		cin >> order;

		if (order == 1)
		{
			cin >> key >> value;

			db.insert(make_pair(key, value));
		}

		else if (order == 2)
		{
			cin >> key >> value;

			it1 = db.lower_bound(key);
			it2 = db.upper_bound(key);

			//해당 키가 있는경우
			if (it1 != db.end() && (*it1).first == key)
				(*it1).second = value;

			//해당 키가 없는 경우
			else
			{
				if (it1 != db.begin())
					it1--;

				if (it2 == db.end())
					it2--;

				//같은것을 찾았을 경우
				if ((*it1).first == (*it2).first)
				{
					if (abs((*it1).first - key) <= k)
						(*it1).second = value;
				}

				else
				{
					//유일한 key가 없는 경우
					if (abs((*it1).first - key) == abs((*it2).first - key))
						continue;

					if (abs((*it1).first - key) < abs((*it2).first - key))
					{
						if (abs((*it1).first - key) <= k)
							(*it1).second = value;
					}

					if (abs((*it1).first - key) > abs((*it2).first - key))
					{
						if (abs((*it2).first - key) <= k)
							(*it2).second = value;
					}
				}
			}
		}

		else if (order == 3)
		{
			cin >> key;

			it1 = db.lower_bound(key);
			it2 = db.upper_bound(key);

			//해당 키가 있는경우
			if (it1 != db.end() && (*it1).first == key)
				cout << (*it1).second << "\n";

			//해당 키가 없는 경우
			else
			{
				if (it1 != db.begin())
					it1--;

				if (it2 == db.end())
					it2--;

				//같은것을 찾았을 경우
				if ((*it1).first == (*it2).first)
				{
					if (abs((*it1).first - key) <= k)
						cout << (*it1).second << "\n";
					else
						cout << -1 << "\n";
				}

				else
				{
					//유일한 key가 없는 경우
					if (abs((*it1).first - key) == abs((*it2).first - key))
					{
						if (abs((*it1).first - key) <= k)
							cout << "?" << "\n";
						else
							cout << -1 << "\n";
					}

					else if (abs((*it1).first - key) < abs((*it2).first - key))
					{
						if (abs((*it1).first - key) <= k)
							cout << (*it1).second << "\n";
						else
							cout << -1 << "\n";
					}

					else if (abs((*it1).first - key) > abs((*it2).first - key))
					{
						if (abs((*it2).first - key) <= k)
							cout << (*it2).second << "\n";
						else
							cout << -1 << "\n";
					}
				}
			}
		}
	}

	return 0;
}