kmjp's blog

競技プログラミング参加記です

TopCoder SRM 776 : Div1 Easy EncloseArea

ここ数回、Easy/Mediumをちゃんと取れてるので良い感じ。
https://community.topcoder.com/stat?c=problem_statement&pm=15917&rd=17799

問題

50*50のグリッドが与えられる。
一部のセルについて、対角線に線を引き、全体で1つの多角形を作ることを考える。
面積Nの多角形を構築せよ。

解法

(0,0)-(50,50)の51*51個ある格子点のうち、X座標とY座標のわが偶数の箇所を考える。
そのうちこの領域の内部にある点は(1,1)-(49,49)まで1201個ある。
各点について、そこを囲うように上下左右に斜めの線を引くと、面積が2の四角形を作ることができる。
そこで、全体が連結となるようN/2個の四角形を取ろう。
選択した格子点とその斜めの点の間で、四角形の内外の差があるなら線を引くようにするとよい。

int B[52][52];

class EncloseArea {
	public:
	vector <string> enclose(int A) {
		if(A%2) return {};
		A/=2;
		
		ZERO(B);
		int x,y;
		
		for(x=1;x<=49;x++) if(A) A--, B[1+(x%2==0)][x]=1;
		
		for(y=3;y<=49;y++) {
			for(x=1+(y%2==0);x<=49;x+=2) if(A) A--,B[y][x]=1;
		}
		
		if(A>0) return {};
		
		vector<string> S;
		FOR(y,50) {
			S.push_back(string(50,'.'));
			FOR(x,50) {
				if((B[y][x]==1)!=(B[y+1][x+1]==1)) S[y][x]='/';
				if((B[y][x+1]==1)!=(B[y+1][x]==1)) S[y][x]='\\';
			}
			cout<<S[y]<<endl;
		}
		
		return S;
	}
}

まとめ

350ptはびっくりした。
途中タイムロスもあったの勿体ないな。