Submission #1354733

#TimeUsernameProblemLanguageResultExecution timeMemory
1354733gvancakPaint By Numbers (IOI16_paint)C++20
59 / 100
1 ms428 KiB
//#include "paint.h"
#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define ll long long
using namespace std;
//const int S_MAX_LEN = 200 * 1000;
//char buf[S_MAX_LEN + 1];

vector <vector<bool> > calc_dp(string s,vector <int> c){
	
	int n=s.size();
	int k=c.size();
	reverse(s.begin(),s.end());
	s+='0';
	reverse(s.begin(),s.end());
	reverse(c.begin(),c.end());
	c.pb(0);
	reverse(c.begin(),c.end());
	vector <vector<bool> > dp(n+5, vector<bool>(k+5));
	for (int i=0; i<=n; i++) 
	for (int j=0; j<=k; j++) 
	dp[i][j]=0;
	dp[0][0]=1;
	// prep 
	int pw[n+5];
	pw[0]=0;
	for (int i=1; i<=n; i++){
		pw[i]=pw[i-1];
		if (s[i]=='_') pw[i]++;
	}
	int x,y;
	
	for (int i=1; i<=n; i++) {
		for (int j=0; j<=k; j++){
			if (i<c[j]) break;
			if (s[i]!='X' && dp[i-1][j]==1) { dp[i][j]=1; continue; }
			x=i-c[j]+1; y=pw[i]-pw[x-1];
			if (y!=0) continue;
			if (j==1){ dp[i][j]=1; continue; }
			if (s[i-c[j]]=='X') continue;
			if (i==c[j] || j==0) continue;
			dp[i][j]=dp[i-c[j]-1][j-1];
		}
	}
	return dp;
	
}

string solve_puzzle(string s, vector<int> c) {
	
	string ans;
	ans.clear();
	vector <vector <bool> > left_dp=calc_dp(s,c);
	reverse(s.begin(),s.end());
	reverse(c.begin(),c.end());
	vector <vector <bool> > right_dp=calc_dp(s,c);
	reverse(s.begin(),s.end());
	reverse(c.begin(),c.end());
	// dp calc
	int n=s.size();
	int k=c.size();
	reverse(s.begin(),s.end());
	s+='0';
	reverse(s.begin(),s.end());
	reverse(c.begin(),c.end());
	c.pb(0);
	reverse(c.begin(),c.end());
	// 0 -> 1 index
	vector <bool> white(n+5);
	for (int i=1; i<=n; i++){
		if (s[i]=='X') continue;
		if (s[i]=='_'){
			white[i]=1; continue;
		}
		for (int j=0; j<=k; j++){
			//cout<<i<<j<<endl;
			int ind1=i-1;  ind1=max(ind1,0);
			int ind2=n-(i+1)+1;  ind2=max(ind2,0);
		//	cout<<ind1<<j<<ind2<<k-j<<endl;
			if (left_dp[ind1][j]==1 && right_dp[ind2][k-j]==1){
			//	cout<<i<<" "<<left_dp[ind1][j]<<" "<<right_dp[ind2][k-j]<<endl;
				white[i]=1; break;
			}
		//	cout<<"a";
		}
	}
	
	// white filled
	
	int pw[n+5];
	pw[0]=0;
	for (int i=1; i<=n; i++){
		pw[i]=pw[i-1];
		if (s[i]=='_') pw[i]++;
	}
	int x,y;
//	cout<<"A";
	vector <int> black(n+5),cnt(n+5);
	int sum=0;
	for (int j=1; j<=k; j++){
		for (int i=1; i<=n; i++){
			if (i+c[j]-1>n) continue; 
		//	cout<<j<<" "<<i<<endl;
			x=i+c[j]-1; y=pw[x]-pw[i-1];
			if (y!=0) continue;
			if (i!=1 && j!=1 && s[i-1]=='X') continue;
			if (i!=n && j!=k && s[i+1]=='X') continue;
		//	cout<<"a"<<endl;
			if (j==1){
			//	if (k==1 && left_dp[i-1][0]==1) { black[i]++; black[i+c[j]]--; continue; }
			//	if (k==1) continue;
				int hm=i+c[j]+1;
				if (k==1) hm--;
				y=n-(hm)+1;
				if (y>n || y<0) continue;
				if (right_dp[y][k-1]==1 && left_dp[i-1][0]==1){
					black[i]++; black[i+c[j]]--; continue;
				}
				continue;
			}
			
			if (j==k){
				y=i-2;
				if (y<0) continue;
				bool ok=0;
				if ((n-(i+c[j])+1<0 || n-(i+c[j])+1>n || right_dp[n-(i+c[j])+1][0]==1)) ok=1;
				if (left_dp[y][j-1]==1 && ok==1){
					black[i]++; black[i+c[j]]--; continue;
				}
				continue;
			}
			y=i-2; int yy=n-(i+c[j]+1)+1;
			if (y<0 || yy<0 || yy>n) continue;
			if (left_dp[y][j-1]==1 && right_dp[yy][k-j]==1){
				black[i]++; black[i+c[j]]--;
			}
			
			
		}
	//	cout<<j<<endl;
	}
//	cout<<"A";
	for (int i=1; i<=n; i++) black[i]+=black[i-1];
	
	for (int i=1; i<=n; i++){
		if (black[i]>0 && white[i]>0) ans+='?';
		else
		if (white[i]>0) ans+='_';
		else
		ans+='X';
	}
	
	return ans;
}
/*
int main() {
    assert(1 == scanf("%s", buf));
    std::string s = buf;
    int c_len;
    assert(1 == scanf("%d", &c_len));
    std::vector<int> c(c_len);
    for (int i = 0; i < c_len; i++) {
        assert(1 == scanf("%d", &c[i]));
    }
    string ans = solve_puzzle(s, c);


    printf("%s\n", ans.data());
    return 0;
}*/
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...