100722A
这道题抄了答案:
思路:旋转,其实只用旋转四次,因为在换行的过程中旋转其实是没有意义的,因为行列只不过转了个角度。然后主要的是行列的交换,这里我很头疼,写了个盲目搜索,当然wa掉了
问了问某位同志,是这样做的,很巧妙:其实这是一个全排列,一个三个数的全排列套了三个数的全排列,然后该怎么做呢?这里运用了一个巧妙的方法:range
range很巧妙,分两种情况:当我选完了三列时,这时我需要新的一列,那么我返回(0,8),意思是下一个列可以从(0,8)之间没用过的任选。第二呢,是我正在选三列中的一列,这时
我看看上一列我选的什么,这次我选的只能是(上一列设为x)[x/3*3,x/3*3+2]举个例子:(0,1,2) (3,4,5)(6,7,8)其实就是这三个块,他们每三个数必须绑在一起
然后我搜完了列之后搜行(搜行的时候我犯了个错误,对应残缺的数独下标没想清楚,debug了很长时间,下次应该想清楚)然后就是重复同样的过程,只不过要加上置换,
置换需要用一个额外的数组记录是那一列的时候替换的,因为会导致还原的时候不知道哪些要还原,然后就好了。
#include<iostream>
#include<cstring>
#include<cstdio> using namespace std; typedef pair<int,int> pii; string s;
int used_col[],used_row[],place[];
int pos_row[],pos_col[],place_flag[];
int b[][],c[][]; void init()
{
memset(place_flag,-,sizeof(place_flag));
memset(place,-,sizeof(place));
memset(pos_row,-,sizeof(pos_row));
memset(pos_col,-,sizeof(pos_col));
memset(used_row,,sizeof(used_row));
memset(used_col,,sizeof(used_col));
} pii get_range(int pos,int f)
{
if(pos%==) return pii(,);
int head=;
if(!f) head=pos_row[pos-]/*;
else head=pos_col[pos-]/*;
return pii(head,head+);
} void rotate()
{
int a[][];memset(a,,sizeof(a));
for(int i=;i<;i++)
for(int j=;j<;j++) a[-j-][i]=b[i][j];
for(int i=;i<;i++)
for(int j=;j<;j++) b[i][j]=a[i][j];
} bool go_col(int d)
{
if(d==) return true;
pii range=get_range(d,);
for(int i=range.first;i<=range.second;i++) if(!used_col[i])
{
used_col[i]=;
pos_col[d]=i;
bool flag=false;
for(int j=;j<;j++)
{
int x=b[pos_row[j]][pos_col[d]],y=c[j][d];
if(y==) continue;
if(place[x]!=-&&place[x]!=y) {flag=true;break;}
if(place[x]==-)
{
place[x]=y;
place_flag[x]=d;
}
}
if(!flag) if(go_col(d+)) return true;
for(int j=;j<;j++)
{
int x=b[pos_row[j]][pos_col[d]];
if(place_flag[x]==d) {place_flag[x]=-;place[x]=-;}
}
used_col[i]=;
pos_col[d]=-;
}
return false;
} bool go_row(int d)//行
{
if(d==) return go_col();
pii range=get_range(d,);
for(int i=range.first;i<=range.second;i++)
{
if(!used_row[i])
{
used_row[i]=;
pos_row[d]=i;
if(go_row(d+)) return true;
used_row[i]=;
pos_row[d]=-;
}
}
return false;
} bool work()
{
for(int i=;i<;i++)
{
init();
rotate();
if(go_row()) return true;
}
return false;
} int main()
{
int T;scanf("%d",&T);
while(T--)
{
for(int i=;i<;i++)
{
cin>>s;
for(int j=;j<;j++)
{
b[i][j]=s[j]-'';
}
}
for(int i=;i<;i++)
{
cin>>s;
for(int j=;j<;j++)
{
c[i][j]=s[j]-'';
}
}
if(work()) printf("Yes\n"); else printf("No\n");
}
return ;
}
100722A的更多相关文章
随机推荐
- WAMP中phpMyAdmin登陆不了问题的解决方法
WAMP中phpMyAdmin登陆不了问题的解决方法
- jmeter的压力测试
Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试. 以下为压力测试的简单介绍 1.在测试计划下增加一个线程组 2.线程组的内容需要进行编辑,根据压力测 ...
- idea常用快捷键
十大Intellij IDEA快捷键 2015-01-16 21:31 122307人阅读 评论(38) 收藏 举报 本文章已收录于: .embody { padding: 10px 10px 10p ...
- [转]mvc3 使用session来存储类来存储用户登陆信息
mvc3 使用session来存储类来存储用户登陆信息 2013-08-26 09:48:56| 分类: NET开发 |举报 |字号 订阅 项目之前的登陆机制是这样的:用户登陆后初始化一个类,类 ...
- 协议的分用以及wireshark对协议的识别
在TCP/IP详解一书中谈到了协议的分用,书中的图1-8如上.图1-8可以很好地解释在互联网的分层结构中,底层的协议头是如何承载上层的不同的协议的.对于链路层而言,以太网首部中有不同帧类型用于表示以太 ...
- gitlab两种连接方式:ssh和http配置介绍
gitlab环境部署好后,创建project工程,在本地或远程下载gitlab代码,有两种方式:ssh和http (1)ssh方式:这是一种相对安全的方式 这要求将本地的公钥上传到gitlab中,如下 ...
- linux系统下对网站实施负载均衡+高可用集群需要考虑的几点
随着linux系统的成熟和广泛普及,linux运维技术越来越受到企业的关注和追捧.在一些中小企业,尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案. 那么如何实 ...
- 树莓派B+安装archlinux arm版
按Archlinux官网操作而来,如有疑问参照官网:http://archlinuxarm.org/platforms/armv6/raspberry-pi 以我自己安装过程举例,我的SD卡挂载在ub ...
- ASP.NET MVC验证 - 自定义验证规则、验证2个属性值不等【待验证】
提示:保存后才提示错误信息 自定义验证特性,继承ValidationAttribute并实现IClientValidatable 这次重写了基类的IsValid()方法的另外一个重载,因为该重载包含了 ...
- nfs客户端报错解决Stale file handle
NFS故障: 场景:客户端挂载是好的.服务端磁盘满了,重新给挂了一快.客户端df -h nfs挂载消失. 客户端报错:Stale file handle 现象如下: [root@test63-spri ...