Submission #428947

#TimeUsernameProblemLanguageResultExecution timeMemory
428947Popax21Painting Squares (IOI20_squares)C++14
0 / 100
147 ms596 KiB
#include <stddef.h>
#include <stdio.h>
#include <assert.h>
#include <vector>
#include "squares.h"

struct edge;

struct node {
	std::vector<edge> edges;
	bool visited;
} nodes[512];

struct edge {
	node *nd;
	int digit;

	edge(node *n, int d) : nd(n), digit(d) {}
};

int seq[1024], iseq[1024], seqi = 0;
bool seq_init = false;

void dfs(node *n, int d) {
	if(n->visited) return;
	n->visited = true;

	int w = (((n - nodes) << 1) | d) & 1023;
	seq[seqi] = w;
	iseq[w] = seqi++;

	dfs(n->edges.front().nd, n->edges.front().digit);
}

std::vector<int> paint(int n) {
	if(!seq_init) {
		//Create a De Brujn sequence, and store the words in a look up table
		for(int w = 0; w < 512; w++) {
			nodes[w].edges.push_back(edge(nodes + (((w<<1) | 0) & 511), 0));
			nodes[w].edges.push_back(edge(nodes + (((w<<1) | 1) & 511), 1));
			nodes[w].visited = false;
		}
		dfs(nodes+0, 0);
		seq_init = true;
	}

	//Init labels from sequence
	std::vector<int> l(n+1);
	for(int i = 0; i < n; i++) l[n] = seq[i];
	l[n] = 10;

	return l;
}

int find_location(int n, std::vector<int> c) {
	assert(c.size() == 10);

	//Is at edge?
	if(c[9] < 0) {
		int p = 0;
		while(c[p] >= 0) p++;
		return n - p;
	}

	//Calculate word
	int w = 0;
	for(int i = 0; i < 10; i++) {
		assert(c[i] >= 0);
		w = (w << 1) | c[i];
	}

	//Lookup in LUT
	// printf("lut %d => %d\n", w, lut[w]);
	return iseq[w];
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...