【AtCoder】ARC095 E - Symmetric Grid 模拟
生活随笔
收集整理的這篇文章主要介紹了
【AtCoder】ARC095 E - Symmetric Grid 模拟
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【題目】E - Symmetric Grid
【題意】給定n*m的小寫字母矩陣,求是否能通過若干行互換和列互換使得矩陣中心對稱。n,m<=12。
【算法】模擬
【題解】首先行列操作獨立,如果已確定行操作,那么兩個在對稱位置的列要滿足條件必須其中一列反轉后和另一列相同,或m為奇數且此列在中間。
已確定了行操作后,枚舉每一列,找到它可以匹配的列直接匹配,后面如果矛盾了就直接無解(因為匹配的列都是確定的,不存在決策問題),復雜度O(nm^2)。
如何確定行操作?枚舉每一行的匹配行,雖然這樣理論上會枚舉n^(n/2)種情況,但其中只有(n-1)!!種情況合法并進入下一過程,故復雜度為O((n-1)!!*nm^2),極限為17962560,實際上列枚舉存在大量返回會更快,甚至直接枚舉列匹配都能2ms AC。
代碼來自:zhan8855
#include <cstdio>char c[15][15],d[15],e[15]; int i,m,n;inline bool dfs2(int x) {if (x>m)return true;if (e[x])return dfs2(x+1);else{int t=0,r=0;for (int i=x;i<=m;i++)if (! e[i])t++;for (int i=x;i<=m;i++)if (! e[i]){e[x]=i,e[i]=x,r=1;for (int j=1;j<=n;j++)if ((c[j][x]!=c[d[j]][i]) || (c[d[j]][x]!=c[j][i])){r=0;break;}if(i==x){if(r&&(t&1)&&dfs2(x+1))return true;}else{if(r){if(dfs2(x+1))return true;else return false;}}/*if ((r) && ((t&1) || (i!=x)) && (dfs2(x+1)))return true;else if(i!=x)return false;*/e[x]=0,e[i]=0;}}return false; }inline bool dfs1(int x) {if (x>n)return dfs2(1);if (d[x])return dfs1(x+1);else{int t=0;for (int i=x;i<=n;i++)if (! d[i])t++;for (int i=x;i<=n;i++)if (! d[i]){d[x]=i,d[i]=x;if (((t&1) || (i!=x)) && (dfs1(x+1)))return true;d[x]=0,d[i]=0;}}return false; }int main() {scanf("%d%d",&n,&m);for (i=1;i<=n;i++)scanf("%s",c[i]+1);if (dfs1(1))puts("YES");elseputs("NO");return 0; } View Code?
轉載于:https://www.cnblogs.com/onioncyc/p/8849156.html
總結
以上是生活随笔為你收集整理的【AtCoder】ARC095 E - Symmetric Grid 模拟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 博弈论学习 | 第七章 Evolutio
- 下一篇: [react] 在React中我们怎么做