Submission #51415

#TimeUsernameProblemLanguageResultExecution timeMemory
51415tincamateiPaint By Numbers (IOI16_paint)C++14
100 / 100
474 ms49044 KiB
#include <bits/stdc++.h>

using namespace std;

#ifndef HOME
#include "paint.h"
#endif

const int MAX_N = 200000;
const int MAX_K = 100;

int white[1+MAX_N];
bool pref[1+MAX_K][1+MAX_N];
bool suff[1+MAX_K][1+MAX_N];
int smen[1+MAX_N+1];

void calcdp(int n, int k, string clues, vector<int> block, bool dp[1+MAX_K][1+MAX_N]) {
	dp[0][0] = true;
	for(int i = 1; i <= n; ++i)
		white[i] = white[i - 1] + (clues[i] == '_');
	
	for(int i = 1; i <= n; ++i) {
		if(clues[i] == 'X')
			dp[0][i] = false;
		else
			dp[0][i] = dp[0][i - 1];
	}

	for(int j = 1; j <= k; ++j) {
		for(int i = block[j]; i <= n; ++i)
			if(clues[i] == '_')
				dp[j][i] = dp[j][i - 1];
			else if(clues[i] == 'X' && clues[i - block[j]] != 'X' && white[i] - white[i - block[j]] == 0)
				dp[j][i] = dp[j - 1][max(i - block[j] - 1, 0)];
			else if(clues[i] == '.') {
				dp[j][i] = dp[j][i - 1];
				if(white[i] - white[i - block[j]] == 0 && clues[i - block[j]] != 'X')
					dp[j][i] |= dp[j - 1][max(i - block[j] - 1, 0)];
			}
	}
}

string solve_puzzle(string clues, vector<int> block) {
	int n, k;
	n = clues.size();
	k = block.size();
	clues.insert(clues.begin(), 0);
	block.insert(block.begin(), 0);

	string result(n, '.');
	
	calcdp(n, k, clues, block, pref);
	
	reverse(clues.begin() + 1, clues.end());
	reverse(block.begin() + 1, block.end());

	calcdp(n, k, clues, block, suff);

	reverse(clues.begin() + 1, clues.end());
	reverse(block.begin() + 1, block.end());
	
	clues.push_back('.');
	
	/*for(int j = 0; j <= k; ++j) {
		for(int i = 1; i <= n; ++i)
			printf("%d ", pref[j][i]);
		printf("\n");
	}
	printf("\n");
	for(int j = 0; j <= k; ++j) {
		for(int i = 1; i <= n; ++i)
			printf("%d ", suff[j][i]);
		printf("\n");
	}
	printf("\n");
*/
	for(int i = 0; i <= k; ++i)
		for(int j = 1; j <= n; ++j) {
			if(clues[j] != 'X' && pref[i][j - 1] && suff[k - i][max(n - j, 0)])
				result[j - 1] = '_';
		}
	
	for(int i = 1; i <= n; ++i)
		white[i] = white[i - 1] + (clues[i] == '_');

	for(int j = 1; j <= k; ++j) {
		for(int i = block[j]; i <= n; ++i) {
			if(white[i] - white[i - block[j]] == 0 && // ultima bucata nu are restrictii albe
			   clues[i + 1] != 'X' && 
				 clues[i - block[j]] != 'X' &&
				 pref[j - 1][max(i - block[j] - 1, 0)] &&
				 suff[k - j][max(n - i - 1, 0)]) {
	//			printf("Put block %d: %d <-> %d\n", j, i - block[j] + 1, i);
				smen[i - block[j] + 1]++;
				smen[i + 1]--;
			}
		}
	}
	
	int p = 0;
	for(int i = 1; i <= n; ++i) {
		p += smen[i];
		if(p > 0 && result[i - 1] == '_')
			result[i - 1] = '?';
		else if(p > 0)
			result[i - 1] = 'X';
	}

	return result;
}

#ifdef HOME
int main() {
#ifdef HOME
	FILE *fin = fopen("input.in", "r");
	FILE *fout = fopen("output.out", "w");
#else
	FILE *fin = stdin;
	FILE *fout = stdout;
#endif
	
	const int S_MAX_LEN = 200 * 1000;
	char buf[S_MAX_LEN + 1];

  assert(1 == fscanf(fin, "%s", buf));
  std::string s = buf;
  int c_len;
  assert(1 == fscanf(fin, "%d", &c_len));
  std::vector<int> c(c_len);
  for (int i = 0; i < c_len; i++) {
    assert(1 == fscanf(fin, "%d", &c[i]));
  }
  std::string ans = solve_puzzle(s, c);

  fprintf(fout, "%s\n", ans.data());

#ifdef HOME
	fclose(fin);
	fclose(fout);
#endif
	return 0;
}
#endif
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...