poj 1021矩阵平移装换后是否为同一个矩阵
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 3081 | Accepted: 1398 |
Description

The player on move may remove (A), (B), (A, B), (A, B, C), or (B,F), etc., but may not remove (A, C), (D, E), (H, I) or (B, G).
For purposes of writing 2D-Nim-playing software, a certain
programmer wants to be able to tell whether or not a certain position
has ever been analyzed previously. Because of the rules of 2D-Nim, it
should be clear that the two boards above are essentially equivalent.
That is, if there is a winning strategy for the left board, the same one
must apply to the right board. The fact that the contiguous groups of
pieces appear in different places and orientations is clearly
irrelevant. All that matters is that the same clusters of pieces (a
cluster being a set of contiguous pieces that can be reached from each
other by a sequence of one-square vertical or horizontal moves) appear
in each. For example, the cluster of pieces (A, B, C, F, G) appears on
both boards, but it has been reflected (swapping left and right),
rotated, and moved. Your task is to determine whether two given board
states are equivalent in this sense or not.
Input
first line of the input file contains a single integer t (1 ≤ t ≤ 10),
the number of test cases, followed by the input data for each test case.
The first line of each test case consists of three integers W, H, and n
(1 ≤ W, H ≤ 100). W is the width, and H is the height of the grid in
terms of the number of grid points. n is the number of pieces on each
board. The second line of each test case contains a sequence of n pairs
of integers xi , yi, giving the coordinates of the pieces on the first
board (0 ≤ xi < W and 0 ≤ yi < H). The third line of the test case
describes the coordinates of the pieces on the second board in the same
format.
Output
program should produce a single line for each test case containing a
word YES or NO indicating whether the two boards are equivalent or not.
Sample Input
2
8 5 11
0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 5 2 4 4
0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4
8 5 11
0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 6 1 4 4
0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4
Sample Output
YES
NO 问的是点阵图的同构。
应该有比较科学的方法的,但是我看到网上有一个做法是统计十字走的步数的方法。觉得非常神奇。虽然看起来不怎么科学,但是可能是数据比较水,居然能A。大致思路就是统计每个点能向四个方向走的步数的和,再比较这两个图中每个点是否都能找到一个总步数相同的点与之匹配
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm> using namespace std;
struct node
{
int x;
int y;
} p[]; int map[][],n,w,h;
int sum[][]; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
cin>>w>>h>>n;
memset(map,,sizeof(map));
memset(sum,,sizeof(sum));
for(int i=; i<=n; i++)
{
cin>>p[i].x>>p[i].y;
map[p[i].x][p[i].y]=;
}
for (int i = ; i <= n; i ++)
{
int xx = p[i].x,yy = p[i].y,x,y,cnt = ;
for (x = xx,y = yy; map[x][y] && y < h; ++y,++cnt);
for (x = xx,y = yy; map[x][y] && x < w; ++x,++cnt);
for (x = xx,y = yy; map[x][y] && y >= ; --y,++cnt);
for (x = xx,y = yy; map[x][y] && x >= ; --x,++cnt);
sum[][i] = cnt;
}
memset(map,,sizeof(map));
for(int i=; i<=n; i++)
{ cin>>p[i].x>>p[i].y;
map[p[i].x][p[i].y]=;
}
for (int i = ; i <= n; i ++)
{
int xx = p[i].x,yy = p[i].y,x,y,cnt = ;
for (x = xx,y = yy; map[x][y] && y < h; ++y,++cnt);
for (x = xx,y = yy; map[x][y] && x < w; ++x,++cnt);
for (x = xx,y = yy; map[x][y] && y >= ; --y,++cnt);
for (x = xx,y = yy; map[x][y] && x >= ; --x,++cnt);
sum[][i] = cnt;
} sort(sum[]+,sum[]++n);
sort(sum[]+,sum[]++n); int falg=;
for(int i=; i<n; i++)
{
if(sum[][i]!=sum[][i])
{
falg=;
break;
}
}
if(!falg)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return ;
}
思路:把每个点的值设为连续的x轴点数和连续的y轴点数之和。排序之后,如果相等,则两个图相等。证明的话可想而知 过程:一次A了 代码:
#include
#include int x[],y[];
int map[][];
int left[],right[]; int main(){
int cas;
int i,j,k;
int w,h,n;
int tmp; scanf("%d",&cas);
for(i = ; i < cas; i++){
scanf("%d%d%d",&w,&h,&n); memset(map,,sizeof(map));
for(j = ; j < n; j++){
scanf("%d%d",&x[j],&y[j]);
map[x[j]][y[j]] = ;
} memset(left,,sizeof(left));
for(j = ; j < n; j++){
tmp = x[j];
while(tmp >= &&map[tmp][y[j]] == ){
left[j]++;
tmp--;
} tmp = x[j]+;
while(tmp < w&&map[tmp][y[j]] == ){
left[j]++;
tmp++;
} tmp = y[j]-;
while(tmp >= &&map[x[j]][tmp] == ){
left[j]++;
tmp--;
} tmp = y[j]+;
while(tmp < h&&map[x[j]][tmp] == ){
left[j]++;
tmp++;
}
} memset(map,,sizeof(map));
for(j = ; j < n; j++){
scanf("%d%d",&x[j],&y[j]);
map[x[j]][y[j]] = ;
}
memset(right,,sizeof(right));
for(j = ; j < n; j++){
tmp = x[j];
while(tmp >= &&map[tmp][y[j]] == ){
right[j]++;
tmp--;
} tmp = x[j]+;
while(tmp < w&&map[tmp][y[j]] == ){
right[j]++;
tmp++;
} tmp = y[j]-;
while(tmp >= &&map[x[j]][tmp] == ){
right[j]++;
tmp--;
} tmp = y[j]+;
while(tmp < h&&map[x[j]][tmp] == ){
right[j]++;
tmp++;
}
} for(j = ; j < n; j++){
for(k = ; k < n; k++){
if(left[k-] < left[k]){
tmp = left[k-];
left[k-] = left[k];
left[k] = tmp;
}
}
} for(j = ; j < n; j++){
for(k = ; k < n; k++){
if(right[k-] < right[k]){
tmp = right[k-];
right[k-] = right[k];
right[k] = tmp;
}
}
} for(j = ; j < n; j++){
if(left[j] != right[j]) break;
} if(j == n){
printf("YES\n");
}else{
printf("NO\n");
}
} return ;
}
poj 1021矩阵平移装换后是否为同一个矩阵的更多相关文章
- opencv之深拷贝及浅拷贝,IplImage装换为Mat
一.(1) 浅拷贝: Mat B; B = image // 第一种方式 Mat C(image); // 第二种方式 这两种方式称为浅copy,是由于它们有不同的矩阵头,但是它们共享内存空间,即 ...
- 【计算机视觉】【图像处理】【VS开发】【Qt开发】opencv之深拷贝及浅拷贝,IplImage装换为Mat
原文:opencv之深拷贝及浅拷贝,IplImage装换为Mat 一.(1) 浅拷贝: Mat B; B = image // 第一种方式 Mat C(image); // 第二种方式 这两种方式称 ...
- 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...
- C# DataSet装换为泛型集合
1.DataSet装换为泛型集合(注意T实体的属性其字段类型与dataset字段类型一一对应) #region DataSet装换为泛型集合 /// <summary> /// 利用反射和 ...
- 先装.net后装iis的问题
如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:(即就是先装的是visual stuido 2010的话,在安装IIS 7) 32位的Windows:----------- ...
- oracle中的装换函数
日期装换成字符的函数:TO_CHAR(date[,fmt[,params]]) 默认格式:DD-MON-RR 参数说明: date:将要装换的日期 fmt:装换的格式 params:日期的语言(可以不 ...
- C++实现离散余弦变换(参数为Eigen矩阵)
C++实现离散余弦变换(参数为Eigen矩阵) 问题描述 昨天写了一个参数为二维指针为参数的离散余弦变换,虽然改进了参数为二维数组时,当数组大小不确定时声明函数时带来的困难,但使用指针作为参数也存在一 ...
- 先装IIS后装.Net Framework
1.动态页面和静态页面的区别 动态页面(动态网站):通过C#代码(或别的语言)与服务器的交互的实现(比如新建一个ashx一般处理程序中的C#代码就可以和服务器实现交互,修改数据库,上传图片等都属于和服 ...
- 处理程序“SimpleHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” 先装 .Net 后装 IIS
以管理员身份打开 cmd 运行 cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 运行 aspnet_regiis.exe -i 重新注册 原因是先 ...
随机推荐
- NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)
摘要 NHibernate的多对多关系映射由many-to-many定义. 从这里下载本文的代码NHibernate Demo 1.修改数据库 添加Product表 添加ProductOrder表 数 ...
- CentOS网络配置详解
转载于CentOS中文站:http://www.centoscn.com/CentOS/2015/0507/5376.html一.配置文件详解 在RHEL或者CentOS等Redhat系的Linux系 ...
- Brn系列商城4.1正式发布,欢迎大家下载体验
此次升级内容如下: 独立IP搜索策略 独立文件上传策略 添加退换货功能 重构支付方式 常规性修复和改进 下载地址:http://www.brnshop.com
- android_Activity之Button_OnClickListener
今天我们要讲的主要是四大组件之一Activity 什么是Android 的四大组件呢?接下来简单了解下. 1.Activity Activity就是我们应用程序的界面,主要用来跟我们的用户进行交互的 ...
- bs4的学习
soup = BeautifulSoup(html,'html.parser') #'html.parser'是html解析器必须有soup.find_all("a") #等价于 ...
- 修改myeclipse的servlet模板
今天修改myeclipse的servlet模板时,发生 Could not create the view: An unexpected exception was thrown.错误. 解决方案:1 ...
- 连接Oracle的帮助类
package util; import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedState ...
- ADB理解
在做手机测试时候,经常用到的命令就是adb.如adb shell,adb devices,adb logcat等等 那么什么是adb,怎么用呢? 一.adb adb的全称为Android Debug ...
- MySQL表分区
MySQL的表分区 一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了.如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以 ...
- WebStorm常用设置和常用快捷键
今天下载了最新版本的WebStorm 7.反正又要重新设置一番了,干脆写下来记录到博客里面,免得以后每次忘了还要到处搜索比较麻烦. 加速 禁用多余的插件,关掉没必要的代码检查项.webstorm慢的原 ...