AtCoder Regular Contest 095E - Symmetric Grid
$n \leq 12,m \leq 12$,$n$行$m$列小写字母,现可做无数次操作:交换两行;交换两列。问是否有可能把他变成中心对称的。
没有去想分组枚举的复杂度QAQ
行和列的操作顺序是随意的。假如说在一种最优方案中,操作是行行行……行列列列……列行行行……行列列列……列,那您把后面那堆行和前面那堆列换一下准保没问题:在一行的字母是不会变成不在同一行的,在一列的字母是不会变成不在同一列的,所以我瞄准最优方案,先把行放好位置,然后调列,一定能调好。可能比较抽象,反正他是对的,具体证明出门见其他大牛博客。
还有一件事,我枚举一种分配方案不需要枚举$n!$,很多都是重复的。怎么讲?先考虑这:我一种行的放法确定好,然后调列看合不合法。要合法的话,每个列都要和另一个列配上,这里的配上,就是一个取反后和另一个相等。如果m是奇数,那得有个列来当回文串放中间。这样子,假设现在放行的方案是$(p_1,p_2,...,p_n)$,如果咱变成$(p_2,p_1,...,p_n,p_{n-1})$,那跟前面那种是完全一样的(如果前面那种配上了这种也配上,如果前面那种配不上这种也配不上)。因此我只要把行打包成$n/2$对,然后每一对对称放,复杂度就会变成:多少啊,我每次从剩下的人里选一个考虑他配谁,选谁无所谓因为谁都要配,然后枚举他配谁,这样复杂度就是$(n-1)*(n-3)*...=(n-1)!!$。最大到10000多一点。行列都这么枚举加剪枝可以过。
诶您啥啊列何必像行那样枚举,每次枚举配上就配上了不改了,因此列枚举复杂度可以变成$n*m*m$,排序+二分可以变成$n*m*log_2m$。
//#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<set>
#include<algorithm>
//#include<math.h>
#include<stdlib.h>
using namespace std; int n,m;
char mp[][]; int a[]; bool vis[],ans=; bool v2[];
bool check()
{
// for (int i=1;i<=n;i++) cout<<a[i]<<' ';cout<<endl;
memset(v2,,sizeof(v2));
bool used=(m&);
for (int i=;i<=m;i++) if (!v2[i])
{
bool flag=;
for (int j=i+;j<=m;j++) if (!v2[j])
{
bool ff=;
for (int k=;k<=n;k++) if (mp[a[k]][i]!=mp[a[n-k+]][j]) ff=;
if (ff) {v2[j]=; flag=; break;}
}
if (!flag)
{
if (used)
{
bool ff=;
for (int k=;k<=n;k++) if (mp[a[k]][i]!=mp[a[n-k+]][i]) ff=;
if (ff) used=;
else return ;
}
else return ;
}
}
return ;
} void dfs(int cur,int pos,bool odd)
{
if (ans) return;
if (cur>n) {ans=check(); return;}
if (vis[cur]) {dfs(cur+,pos,odd); return;} for (int i=cur+;i<=n;i++) if (!vis[i])
{
a[pos]=i; a[n-pos+]=cur;
vis[i]=;
dfs(cur+,pos+,odd);
vis[i]=;
}
if (odd)
{
a[(n>>)+]=cur;
dfs(cur+,pos,);
}
} int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%s",mp[i]+);
dfs(,,n&);
puts(ans?"YES":"NO");
return ;
}
AtCoder Regular Contest 095E - Symmetric Grid的更多相关文章
- AtCoder Regular Contest 080 D - Grid Coloring
地址:http://arc080.contest.atcoder.jp/tasks/arc080_b 题目: D - Grid Coloring Time limit : 2sec / Memory ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
随机推荐
- (转)SpringMVC学习(二)——SpringMVC架构及组件
http://blog.csdn.net/yerenyuan_pku/article/details/72231385 相信大家通过前文的学习,已经对SpringMVC这个框架多少有些理解了.还记得上 ...
- C++类构造函数、析构函数运行机理
http://blog.sina.com.cn/s/blog_6fd68d5f0100n60h.html 前言--构造函数.析构函数的简单理解:1)构造函数---对象被创建时候调用的函数:2)析构函数 ...
- elasticsearch最全详细使用教程:搜索详解
一.搜索API 1. 搜索API 端点地址从索引tweet里面搜索字段user为kimchy的记录 GET /twitter/_search?q=user:kimchy从索引tweet,user里面搜 ...
- 同时使用多个UITableView
1.xib\storyboard中给2个tableView设置constraints(等宽) 方法 : ①设置mainTableView的上\下\左\三部分的约束为0:subTableView上\下\ ...
- 《c++编程思想》关于虚函数在构造函数行为的理解,理解有误,望告知!
<c++编程思想>书上有一段话:在任何构造函数中,可能只是部分形成对象——我们只能知道基类已被初始化,但并不知道哪个类是从这个基类继承来的.然而,虚函数在继承层次上是“向前”和“向外”进行 ...
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- modelsim安装调试
modelsim,debug:“unable to checkout a viewer license necessary for use of the modelsim graphical user ...
- perl:_DATA_ _LINE_ _FILE_
这三个应该是句柄: _DATA_ _FILE_ _LINE_ 没有找到具体介绍...记录于此,已被后续补充.
- 《linux设备驱动开发详解》笔记——6字符设备驱动
6.1 字符设备驱动结构 先看看字符设备驱动的架构: 6.1.1 cdev cdev结构体是字符设备的核心数据结构,用于描述一个字符设备,cdev定义如下: #include <linux/cd ...
- Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍
创建一个 Django 项目及应用 django-admin startproject orm cd orm python manage.py startapp app01 在 models.py 上 ...