# 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:

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");
}


• 评论

• 上一篇
• 下一篇