AtCoder Regular Contest 095 - E Symmetric Grid

E - Symmetric Grid


Time limit : 2sec / Memory limit : 256MB

Score : 700 points

Problem Statement

There is an H×W grid (H vertical, W horizontal), where each square contains a lowercase English letter. Specifically, the letter in the square at the i-th row and j-th column is equal to the j-th character in the string Si.

Snuke can apply the following operation to this grid any number of times:

  • Choose two different rows and swap them. Or, choose two different columns and swap them.

Snuke wants this grid to be symmetric. That is, for any 1iH and 1jW, the letter in the square at the i-th row and j-th column and the letter in the square at the (H+1i)-th row and (W+1j)-th column should be equal.

Determine if Snuke can achieve this objective.

Constraints

  • 1H12
  • 1W12
  • |Si|=W
  • Si consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

H W
S1
S2
:
SH

Output

If Snuke can make the grid symmetric, print YES; if he cannot, print NO.


Sample Input 1

Copy
2 3
arc
rac

Sample Output 1

Copy
YES

If the second and third columns from the left are swapped, the grid becomes symmetric, as shown in the image below:


题意:

给你h*w的字符矩阵,你可以交换任意的行或者列。问你能不能使这个矩阵的每一个mp[i][j]=mp[h+1-i][w+1-j].


POINT:

遍历行的情况,然后判断列能不能合法。

swaped[i]=x代表。I行和x行配对。由于配对是两两的。所以情况数最多是11!!,而不是12!。

对于每一种行配对的情况,判断所有列能不能两两配对。

注意奇数的中间多出一列的情况。


英文题解:

E: Symmetric Grid

Notice that an operation about rows and an operation about columns are commutative. Thus, assume that we firstperform operations about rows, and then operations about columns.

Suppose that we finished operations about rows. How can we check if we can achieve a goal by operations aboutcolumns? Notice that, for each j = 1,2,...,W, the j-th column must be the reverse of the W + 1 j-th column. Inparticular, when W is odd, (W + 1)/2 is a palindrome.

Therefore, we can use the following method do check if we can achieve a goal by operations about columns:Initially, all rows are ”unused”.
Choose a particular unused row. Reverse it, and check if it matches with another unused row.

If it matches with another row, mark the two rows as ”used”.

Otherwise, if W is even, the answer is ”NO”. If W is odd and the current row is not a palindrome, theanswer is ”NO”. If W is odd and the current row is a palindrome, we should put it in the (W + 1)/2-throw. If this row is already filled, the answer is ”NO”.

It works in O(HW 2) time (or by binary search you can do it in O(HW log W ))
If we consider all H! possible orders of rows, it will be too slow. Instead, notice that only the set of pairs ((1,H)-th

rows, (2, H 1)-th rows, . . . ) matters. (In case H is odd, one row is left unpaired.)
Thus, we only need to try all pairings of rows. Since there are at most 11!! = 11
×9×7×5×3×1 = 10395 ways

of pairings, it’s fast enough. 



#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
int n,m;
string s[20];
int swaped[20];
int used[20];
int ans = 0;
bool check()
{
	memset(used,0,sizeof used);
	for(int i=0;i<m;i++){
		for(int j=0;j<m;j++){
			if(used[i]||used[j]||i==j) continue;
			int cur=1;
			for(int k=0;k<n;k++){
				if(s[swaped[k]][i]!=s[k][j]){
					cur=0;
					break;
				}
			}
			if(cur){
				used[i]=used[j]=1;
			}
		}
	}
	int cnt=0,to=0;
	for(int i=0;i<m;i++){
		if(!used[i]){
			cnt++;to=i;
		}
	}
	if(cnt>=2||(m%2==0&&cnt)){
		return false;
	}
	if(!cnt) return true;
	for(int i=0;i<n;i++){
		if(s[swaped[i]][to]!=s[i][to]){
			return false;
		}
	}
	return true;
}


void dfs(int now,bool ji)
{
	if(now==(n+1)/2){
		if(check()){
			ans=1;
		}
		return;
	}
	for(int i=now;i<n;i++){
		for(int j=i+1;j<n;j++){
			if(swaped[i]==-1&&swaped[j]==-1){
				swaped[i]=j;
				swaped[j]=i;
				dfs(now+1,ji);
				swaped[i]=-1;
				swaped[j]=-1;
			}
		}
		if(ji&&swaped[i]==-1){
			swaped[i]=i;
			dfs(now+1,false);
			swaped[i]=-1;
		}
	}

}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		cin>>s[i];
		swaped[i]=-1;
	}
	if(n&1){
		dfs(0,true);
	}else{
		dfs(0,false);
	}
	if(ans) printf("YES\n");
	else printf("NO\n");
}



阅读更多
版权声明:是自己手打的没错 https://blog.csdn.net/Mr_Treeeee/article/details/79950244
个人分类: AtCoder
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭