http://code-festival-2017-quala.contest.atcoder.jp/tasks/code_festival_2017_quala_c
解説
http://code-festival-2017-quala.contest.atcoder.jp/submissions/1617339
H,Wのパリティで場合分けする。
H,Wのどちらも偶数
この場合は、上下左右のブロックが全て同じになるため、同じパターンが4つできることになる。
そのため、全ての文字の個数が4の倍数であればYes
H,Wのどちらかが偶数
説明のため、Wが偶数であるとする。
この場合は、中心の行が横の回分でしか使われないため、ここは2の倍数でいい。
そのため、4で割ると2余る数がW/2個以下で、残りが4の倍数であればいい。
(以下というのは、足りない場合は4の倍数のやつを1つ崩して2つにしればいいため)
H,Wのどちらも奇数
この場合はど真ん中は4で割ると1余る数になる必要(1つ必要)がある。
あとは、4で割ると2余る数が使われるのが(H-1)/2+(W-1)/2以下であればいい。
int H, W; string A[101]; #define NO "No" #define YES "Yes" //-------------------------------------------------------------------------------------------------- string solve() { map<char, int> cnt; rep(y, 0, H) rep(x, 0, W) cnt[A[y][x]]++; if (H % 2 == 0 && W % 2 == 0) { fore(p, cnt) if (p.second % 4) return NO; return YES; } if (H % 2 && W % 2) { map<int, int> c; fore(p, cnt) c[p.second % 4]++; if (c[3]) return NO; if (c[1] != 1) return NO; if (c[2] > (H - 1) / 2 + (W - 1) / 2) return NO; return YES; } if (W % 2) swap(H, W); map<int, int> c; fore(p, cnt) c[p.second % 4]++; if (c[1] || c[3]) return NO; if (c[2] > W / 2) return NO; return YES; } //-------------------------------------------------------------------------------------------------- void _main() { cin >> H >> W; rep(y, 0, H) cin >> A[y]; cout << solve() << endl; }