Submission #59171

#TimeUsernameProblemLanguageResultExecution timeMemory
59171TadijaSebezPaint By Numbers (IOI16_paint)C++11
100 / 100
994 ms50244 KiB
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
const int N=200050;
const int K=102;
bool can[2][N][K];
int b[N],w[N];
int max(int a, int b){ return a>b?a:b;}
bool CanBlack(int l, int r){ return w[r]==w[max(l-1,0)];}
bool CanWhite(int l, int r){ return b[r]==b[max(l-1,0)];}
void DP(int n, int k, bool dp[][K], int x[])
{
	int i,j;
	dp[0][0]=1;
	for(i=1;i<=n;i++) if(CanWhite(i,i)) dp[i][0]=dp[i-1][0];
	for(j=1;j<=k;j++)
	{
		for(i=1;i<=n;i++)
		{
			if(CanWhite(i,i)) dp[i][j]|=dp[i-1][j];
			if(i>=x[j] && CanBlack(i-x[j]+1,i) && CanWhite(i-x[j],i-x[j])) dp[i][j]|=dp[max(i-x[j]-1,0)][j-1];
			//if(i==n && j==k) printf("%i %i %i\n",CanBlack(i-x[j]+1,i),CanWhite(i-x[j],i-x[j]),dp[max(i-x[j]-1,0)][j-1]);
		}
	}
	//printf("Matrix:\n");
	//for(j=0;j<=k;j++)
	//{
	//	for(i=0;i<=n;i++)
	//	{
	//		printf("%i ",dp[i][j]);
	//	}
	//	printf("\n");
	//}
}
int x[K],bl[N];
void Set(int l, int r){ bl[l]++;bl[r+1]--;}
void init(int n){ for(int i=1;i<=n;i++) bl[i]+=bl[i-1];}
string solve_puzzle(string s, vector<int> c)
{
	int n=s.size(),k=c.size(),i,j;
	/*if(k==1 && n==c[0])
	{
		string ans;
		for(i=1;i<=n;i++) ans+='X';
		return ans;
	}*/
	for(i=0;i<k;i++) x[k-i]=c[i];
	for(i=0;i<n;i++)
	{
		if(s[i]=='X') b[n-i]=1;
		else b[n-i]=0;
		if(s[i]=='_') w[n-i]=1;
		else w[n-i]=0;
	}
	b[n+1]=w[n+1]=0;
	for(i=1;i<=n+1;i++) b[i]+=b[i-1],w[i]+=w[i-1];
	DP(n,k,can[1],x);
	for(i=0;i<k;i++) x[i+1]=c[i];
	for(i=0;i<n;i++)
	{
		if(s[i]=='X') b[i+1]=1;
		else b[i+1]=0;
		if(s[i]=='_') w[i+1]=1;
		else w[i+1]=0;
	}
	b[n+1]=w[n+1]=0;
	for(i=1;i<=n+1;i++) b[i]+=b[i-1],w[i]+=w[i-1];
	DP(n,k,can[0],x);
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
		{
			if(i>=x[j] && CanBlack(i-x[j]+1,i) && CanWhite(i-x[j],i-x[j]))
			{
				if(CanWhite(i+1,i+1) && can[0][max(i-x[j]-1,0)][j-1] && can[1][max(n-i-1,0)][k-j])
				{
					Set(i-x[j]+1,i);
				}
			}
		}
	}
	//if(CanBlack(1,x[1]) && CanWhite(x[1]+1,x[1]+1)) Set(1,x[1]);
	//if(CanBlack(n-x[k]+1,n) && CanWhite(n-x[k],n-x[k])) Set(n-x[k]+1,n);
	init(n);
	string ans;
	for(i=0;i<n;i++)
	{
		if(s[i]=='.')
		{
			bool wf=0,bf=0;
			if(bl[i+1]) bf=1;
			for(j=0;j<=k;j++)
			{
				if(can[0][i][j] && can[1][n-i-1][k-j]) wf=1;
				//if(can[0][i+1][j] && can[1][n-i-1][k-j]) bf=1;
				//if(can[0][i][j] && can[1][n-i][k-j]) bf=1;
			}
			if(bf && wf) ans+='?';
			if(bf && !wf) ans+='X';
			if(!bf && wf) ans+='_';
			//if(!bf && !wf) printf("%i:->???<-\n",i+1);
		}
		else ans+=s[i];
	}
	return ans;
}
/*int main()
{
	string s;
	vector<int> c;
	int n,k,i;
	cin >> s;
	scanf("%i",&k);
	c.resize(k);
	for(i=0;i<k;i++) scanf("%i",&c[i]);
	cout << solve_puzzle(s,c) << "\n";
	return 0;
}*/
#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...