제출 #1074281

#제출 시각아이디문제언어결과실행 시간메모리
1074281Elias자동 인형 (IOI18_doll)C++17
100 / 100
110 ms19760 KiB
#include <bits/stdc++.h>

using namespace std;

#ifndef _DEBUG
#include "doll.h"
#else
void answer(std::vector<int> C, std::vector<int> X, std::vector<int> Y);
#endif

void wrong(const char *MSG)
{
	printf("Wrong Answer: %s\n", MSG);
	assert(false);
	exit(0);
}

void sim(vector<int> A, vector<int> c, vector<int> x, vector<int> y, int N, int M)
{
	int S = x.size();
	auto IC = c;
	auto IX = x;
	auto IY = y;
	constexpr int p_MAX = 20000000;
	constexpr int s_MAX = 400000;

	if (S > s_MAX)
	{
		char str[50];
		sprintf(str, "over %d switches", s_MAX);
		wrong(str);
	}
	for (int i = 0; i <= M; ++i)
	{
		if (!(-S <= IC[i] && IC[i] <= M))
		{
			wrong("wrong serial number");
		}
	}
	for (int j = 1; j <= S; ++j)
	{
		if (!(-S <= IX[j - 1] && IX[j - 1] <= M))
		{
			wrong("wrong serial number");
		}
		if (!(-S <= IY[j - 1] && IY[j - 1] <= M))
		{
			wrong("wrong serial number");
		}
	}

	int P = 0;
	std::vector<bool> state(S + 1, false);
	int pos = IC[0];
	int k = 0;
	FILE *file_log = fopen("log.txt", "w");
	fprintf(file_log, "0\n");
	for (;;)
	{
		fprintf(file_log, "%d\n", pos);
		if (pos < 0)
		{
			if (++P > p_MAX)
			{
				fclose(file_log);
				char str[50];
				sprintf(str, "over %d inversions", p_MAX);
				wrong(str);
			}
			state[-pos] = !state[-pos];
			pos = state[-pos] ? IX[-(1 + pos)] : IY[-(1 + pos)];
		}
		else
		{
			if (pos == 0)
			{
				break;
			}
			if (k >= N)
			{
				fclose(file_log);
				wrong("wrong motion");
			}
			if (pos != A[k++])
			{
				fclose(file_log);
				wrong("wrong motion");
			}
			pos = IC[pos];
		}
	}
	fclose(file_log);
	if (k != N)
	{
		wrong("wrong motion");
	}
	for (int j = 1; j <= S; ++j)
	{
		if (state[j])
		{
			wrong("state 'Y'");
		}
	}
	// printf("Accepted: %d %d\n", S, P);
}


int n, m;
vector<int> a;
vector<vector<int>> pos;
int cur = 1;

vector<int> c, x, y;

int kgl, pgl;

void build(int i, int l, int r)
{
	int mid = (l + r) / 2;
	if (mid <= pgl)
		x[-i - 1] = -1;
	else
	{
		if (l != mid)
		{
			x[-i - 1] = -cur;
			cur++;
			x.push_back(0);
			y.push_back(0);
			build(x[-i - 1], l, mid);
		}
		else
		{
			x[-i - 1] = 3 * n;
		}
	}
	if (mid + 1 != r)
	{
		y[-i - 1] = -cur;
		cur++;
		x.push_back(0);
		y.push_back(0);
		build(y[-i - 1], mid + 1, r);
	}
	else
	{
		y[-i - 1] = 3 * n;
	}
}

void build_sgt(int nod)
{
	cur = 2;
	kgl = __lg(n);
	if ((1 << kgl) < n)
		kgl++;
	pgl = (1 << kgl) - (int)n;
	build(nod, 1, (1 << kgl));
}

int cr = 0;
vector<int> vis;

void fix(int i)
{
	if (i == 0)
		return;
	if (i >= 1)
	{
		cr++;
		fix(c[i]);
		return;
	}

	if (vis[-i - 1] == 0)
	{
		vis[-i - 1] = 1;
		if (x[-i - 1] > 2 * n)
		{
			x[-i - 1] = a[cr];
		}
		fix(x[-i - 1]);
	}
	else
	{
		vis[-i - 1] = 0;
		if (y[-i - 1] > 2 * n)
		{
			y[-i - 1] = a[cr];
		}
		fix(y[-i - 1]);
	}
}

void create_circuit(int M, vector<int> A)
{
	A.push_back(0);
	n = A.size();
	a = A;
	m = M;
	pos.resize(m + 1);
	
	for (int i = 0; i < a.size(); i++)
		pos[a[i]].push_back(i);

	a.push_back(0);
	c.resize(m + 1);
	for (int i = 0; i <= m; i++)
		c[i] = -1;

	x.push_back(0);
	y.push_back(0);
	vis.resize(2 * n);
	build_sgt(-1);

	fix(-1);

	answer(c, x, y);
}

#ifdef _DEBUG

namespace
{

	constexpr int P_MAX = 20000000;
	constexpr int S_MAX = 400000;

	int M, N;
	std::vector<int> A;

	bool answered;
	int S;
	std::vector<int> IC, IX, IY;

	int read_int()
	{
		int x;
		if (scanf("%d", &x) != 1)
		{
			fprintf(stderr, "Error while reading input\n");
			exit(1);
		}
		return x;
	}

	void wrong_answer(const char *MSG)
	{
		printf("Wrong Answer: %s\n", MSG);
		exit(0);
	}

	void simulate()
	{
		if (S > S_MAX)
		{
			char str[50];
			sprintf(str, "over %d switches", S_MAX);
			wrong_answer(str);
		}
		for (int i = 0; i <= M; ++i)
		{
			if (!(-S <= IC[i] && IC[i] <= M))
			{
				wrong_answer("wrong serial number");
			}
		}
		for (int j = 1; j <= S; ++j)
		{
			if (!(-S <= IX[j - 1] && IX[j - 1] <= M))
			{
				wrong_answer("wrong serial number");
			}
			if (!(-S <= IY[j - 1] && IY[j - 1] <= M))
			{
				wrong_answer("wrong serial number");
			}
		}

		int P = 0;
		std::vector<bool> state(S + 1, false);
		int pos = IC[0];
		int k = 0;
		FILE *file_log = fopen("log.txt", "w");
		fprintf(file_log, "0\n");
		for (;;)
		{
			fprintf(file_log, "%d\n", pos);
			if (pos < 0)
			{
				if (++P > P_MAX)
				{
					fclose(file_log);
					char str[50];
					sprintf(str, "over %d inversions", P_MAX);
					wrong_answer(str);
				}
				state[-pos] = !state[-pos];
				pos = state[-pos] ? IX[-(1 + pos)] : IY[-(1 + pos)];
			}
			else
			{
				if (pos == 0)
				{
					break;
				}
				if (k >= N)
				{
					fclose(file_log);
					wrong_answer("wrong motion");
				}
				if (pos != A[k++])
				{
					fclose(file_log);
					wrong_answer("wrong motion");
				}
				pos = IC[pos];
			}
		}
		fclose(file_log);
		if (k != N)
		{
			wrong_answer("wrong motion");
		}
		for (int j = 1; j <= S; ++j)
		{
			if (state[j])
			{
				wrong_answer("state 'Y'");
			}
		}
		printf("Accepted: %d %d\n", S, P);
	}

} // namespace

void answer(std::vector<int> C, std::vector<int> X, std::vector<int> Y)
{
	if (answered)
	{
		wrong_answer("answered not exactly once");
	}
	answered = true;
	// check if input format is correct
	if ((int)C.size() != M + 1)
	{
		wrong_answer("wrong array length");
	}
	if (X.size() != Y.size())
	{
		wrong_answer("wrong array length");
	}
	S = X.size();
	IC = C;
	IX = X;
	IY = Y;
}

int main()
{
	M = read_int();
	N = read_int();
	A.resize(N);
	for (int k = 0; k < N; ++k)
	{
		A[k] = read_int();
	}

	answered = false;
	create_circuit(M, A);
	if (!answered)
	{
		wrong_answer("answered not exactly once");
	}
	FILE *file_out = fopen("out.txt", "w");
	fprintf(file_out, "%d\n", S);
	for (int i = 0; i <= M; ++i)
	{
		fprintf(file_out, "%d\n", IC[i]);
	}
	for (int j = 1; j <= S; ++j)
	{
		fprintf(file_out, "%d %d\n", IX[j - 1], IY[j - 1]);
	}
	fclose(file_out);
	simulate();
	return 0;
}

#endif

컴파일 시 표준 에러 (stderr) 메시지

doll.cpp: In function 'void create_circuit(int, std::vector<int>)':
doll.cpp:203:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  203 |  for (int i = 0; i < a.size(); i++)
      |                  ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...