QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#18647#2357. Random Chess GameQingyuRE 0ms0kbC++204.3kb2022-01-23 16:08:392022-09-10 00:55:44

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-09-10 00:55:44]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2022-01-23 16:08:39]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

mt19937 mt(736);


enum piece
{
	pawn = 1, knight = 30, bishop = 29, rook = 50, queen = 90, king = 100500
};

auto get_piece(const string &a)
{
	static unordered_map<char, piece> mp = {{'N', knight},
	                                        {'B', bishop},
	                                        {'R', rook},
	                                        {'Q', queen},
	                                        {'K', king}};

	return mp.count(a.front()) ? mp.at(a.front()) : pawn;
}


auto get_pos(string lm)
{
	while (lm.size() > 2 && !isdigit(lm.back()))
		lm.pop_back();
	lm = lm.substr(lm.size() - 2);

	return lm;
}


class chess
{
	unordered_map<string, piece> mem;
	unordered_set<string> deb;

public:
	chess() : deb({"e4", "Qh5", "Bc4", "Bxd5", "Bxe6", "Qxg6"})
	{
		mem["a8"] = rook;
		mem["b8"] = knight;
		mem["c8"] = bishop;
		mem["d8"] = queen;
		mem["e8"] = king;

		for (char col = 'f'; col <= 'h'; col++)
			mem[col + string(1, '8')] = mem[char('a' + 'h' - col) + string(1, '8')];
		for (char col = 'a'; col <= 'h'; col++)
			mem[col + string(1, '7')] = pawn;
	}


	vector<string> find_kings()
	{
		vector<string> kings;

		for (const auto &it : mem)
			if (it.second == king)
				kings.push_back(it.first);

		return kings;
	}


	void upd(const string &mv)
	{
		if (get_piece(mv) == king)
			for (const auto &it : find_kings())
				mem.erase(it);

		mem[get_pos(mv)] = get_piece(mv);
	}


	void upd_white(const string &mv)
	{
		deb.erase(mv);
	}


	piece get(const string &pos)
	{
		return mem[get_pos(pos)];
	}


	auto debut(int num)
	{
		return num < 6 ? deb : unordered_set<string>{};
	}
};


template<class T>
bool cont(const string &wh, T what)
{
	return wh.find(what) != string::npos;
}


int dist(const string &a, const string &b)
{
	return abs(a[0] - b[0]) + abs(a[1] - b[1]);
}


string choose_a_move(vector<string> moves, const string &last_move, chess &gm, int num)
{
	auto est = [&gm, &last_move, &num](const string &a) {
		return tuple{!cont(a, '+'),
		             cont(a, '='),
		             cont(a, 'x'),
		             !cont(a, last_move),
		             cont(a, 'x') ? 10 * gm.get(a) - 7 * get_piece(a) : 0,
		             dist(get_pos(a), gm.find_kings()[0]) > 2,
		             false};
	};

	auto cmp = [&gm, &est, &num](const string &a, const string &b) {
		if (b.find('#') != string::npos)
			return false;
		if (a.find('#') != string::npos)
			return true;

		unordered_set<string> pref = gm.debut(num);

		if (pref.count(a))
			return true;
		if (pref.count(b))
			return false;

		if (a.find('=') != string::npos && b.find('=') != string::npos)
			return get_piece(a.substr(a.size() - 1)) > get_piece(b.substr(b.size() - 1));

		auto qa = est(a);
		auto qb = est(b);

		if (qa != qb)
			return qa > qb;
		if (get_piece(a) == pawn && get_piece(b) == pawn)
		{
			if (a[1] != b[1])
				return a[1] > b[1];
			return abs(a.front() - 'e') > abs(b.front() - 'e');
		}

		if (num > 50 && get_piece(a) == king && get_piece(b) == king)
			return dist(get_pos(a), gm.find_kings()[0]) < dist(get_pos(b), gm.find_kings()[0]);

		return false;
	};

	shuffle(moves.begin(), moves.end(), mt);

	return *min_element(moves.begin(), moves.end(), cmp);
}


void solve(istream &cin = std::cin, ostream &cout = std::cout)
{
	int cnt = 0;
	string str;

	const string res = "result: ", wm = "white_moves: ", bm = "black_move: ", draw = "drawn";
	string lm;

	chess gm;

	while (true)
	{
		getline(cin, str);

		if (str.find(res) != string::npos)
			break;

		if (str.find(wm) != string::npos)
		{
			str = str.substr(wm.size());

			stringstream ss(str);

			vector<string> moves;

			while (ss >> str)
				moves.push_back(str);

			auto dec = choose_a_move(moves, lm, gm, cnt++);

			cout << dec << endl << flush;
			gm.upd_white(dec);
		}

		if (str.find(bm) != string::npos)
		{
			lm = get_pos(str);
			gm.upd(str.substr(bm.size()));
		}
	}
}


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

	cout << fixed;

#ifdef LOCAL
	auto st = clock();

	ifstream fin("../input.txt");

	solve();

	cout << "clock: " << (clock() - st) / (double) CLOCKS_PER_SEC << endl;
#else
	solve();
#endif

	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Interactor Dangerous Syscalls

input:


output:


result: