HNU暑假训练第一场C.Ninja Map
一、题目大意
Intersections of Crossing Path City are aligned to a grid. There are N east-west streets which are numbered from 1 to N, from north to south. There are also N north-south streets which are numbered from 1 to N, from west to east. Every pair of east-west and north-south streets has an intersection; therefore there are N2 intersections which are numbered from 1 to N2.
Surprisingly, all of the residents in the city are Ninja. To prevent outsiders from knowing their locations, the numbering of intersections is shuffled.
You know the connections between the intersections and try to deduce their positions from the information. If there are more than one possible set of positions, you can output any of them.
对于一个矩阵,给出矩阵中每个节点之间的相互连接关系,要求还原矩阵。
二、思路
观察可得,对于任意一个矩阵,四个拐角处的元素都有一个特点——度为2。因此可以考虑,从外向里一圈一圈的放置元素,在一轮放置结束后,将其他节点的度作相应调整——所有与本轮中放置的节点相关联的节点度数减一。
则可以得到新的拐角元素。对于每一层,都可以枚举度小于2<考虑奇数宽度最中间的一个元素度为0>的元素的起始位置。则也因此可以由节点开始遍历本层元素。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stack>
#include<vector>
#include<string>
#include<string.h>
#include<queue>
using namespace std; #define ll intmax_t
#define pp pair<int,int>
#define veci vector<int> const int MAXN=;
int mapp[MAXN][MAXN];
pp coors[MAXN*MAXN];
int n,summ,s_ele;
int du[MAXN*MAXN];
veci G[MAXN*MAXN];
veci que; int addx[]={,,,-};
int addy[]={,,-,}; void show()
{
for(int i=;i<n;++i)
{
for(int j=;j<n;++j)
{
cout<<mapp[i][j];
if(j == n-)cout<<endl;
else cout<<" "; }
}
} void mark(int now,int x,int y)
{
que.push_back(now);
coors[now] = make_pair(x,y);
mapp[x][y] = now;
summ--;
} bool check_legal(int x,int y,int now)
{
int len = G[now].size(); if(x<||x>=n||y<||y>=n)return false;
if(mapp[x][y] != -)return false; for(int i=;i<;++i)
{
int tx = x + addx[i];
int ty = y + addy[i];
if(tx<||tx>=n||ty<||ty>=n)continue;
if(mapp[tx][ty] == -)continue;
bool succ = ;
for(int j=;j<len;++j)
{
int tar = G[now][j];
if(mapp[tx][ty] == tar)
{
succ = ;
break;
}
}if(!succ)return false;
}return true;
} void set_first(int now,int dep)
{
int d1 = dep;
int d2 = n--dep;
int x[] = {d1,d1,d2,d2};
int y[] = {d1,d2,d1,d2};
for(int i=;i<;++i)
{
if(check_legal(x[i],y[i],now))
{
mark(now,x[i],y[i]);
break;
}
}
} bool check_dep(int x,int y,int dep)
{
if(x<||x>=n||y<||y>=n)return false;
int d1 =dep;
int d2 = n--dep;
return x == d1 || x == d2 || y == d1 || y == d2;
} void dfs(int now,int dep)
{
// cout<<now<<endl;
int x = coors[now].first;
int y = coors[now].second;
pp next_coors[];
for(int i=;i<;++i)
{
next_coors[i] = make_pair(x+addx[i],y+addy[i]);
}
int len = G[now].size();
for(int i=;i<len;++i)
{
int tar = G[now][i];
if(coors[tar].first != -)continue;
if(du[tar]==)continue;
for(int j=;j<;++j)
{
int tx = next_coors[j].first;
int ty = next_coors[j].second;
if(check_dep(tx,ty,dep)&&check_legal(tx,ty,tar))
{
mark(tar,tx,ty);
dfs(tar,dep);
break;
}
}
}
} void flush_du()
{
int len = que.size();
for(int i=;i<len;++i)
{
int now = que[i];
int len1 = G[now].size();
for(int j = ;j<len1;++j)
{
int tar = G[now][j];
du[tar] -- ;
if(du[tar] == )s_ele = tar;
}
}
} void init()
{
memset(mapp,-,sizeof(mapp));
int len = *n*n -*n;
for(int i=;i<len;++i)
{
int a,b;
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
summ = len = n*n;
for(int i=;i<=len;++i)
{
coors[i] = make_pair(-,-);
du[i] = G[i].size();
if(du[i] == )s_ele = i;
}
int dep = ;
while(summ )
{
que.clear();
set_first(s_ele,dep);
dfs(s_ele,dep);
flush_du();
dep ++;
}
show();
} int main()
{
cin.sync_with_stdio(false);
while(cin>>n)init(); return ;
}
HNU暑假训练第一场C.Ninja Map的更多相关文章
- 19暑假多校训练第一场-J-Fraction Comparision(大数运算)
链接:https://ac.nowcoder.com/acm/contest/881/J来源:牛客网 题目描述 Bobo has two fractions xaxa and ybyb. He wan ...
- Gym-101653:acific Northwest Regional Contest (2019训练第一场)
本套题没有什么数据结构题,图论题,唯一有价值的就是Q题博弈,在最后面,读者可以直接拉到最下面. (还剩下两个,估计每什么价值的题,懒得补了 M .Polyhedra pro:欧拉公式,V-E+F=2: ...
- 大家一起做训练 第一场 E Number With The Given Amount Of Divisors
题目来源:CodeForce #27 E 题目意思和题目标题一样,给一个n,求约数的个数恰好为n个的最小的数.保证答案在1018内. Orz,这题训练的时候没写出来. 这道题目分析一下,1018的不大 ...
- 大家一起做训练 第一场 B Tournament
题目来源:CodeForce #27 B 有n个人比赛,两两之间都有一场比赛,一共 n * (n - 1) / 2 场比赛.每场比赛的记录方式是 a b,表示在a和b的比赛中,a胜出,b失败. 经过研 ...
- 牛客网多校训练第一场 I - Substring(后缀数组 + 重复处理)
链接: https://www.nowcoder.com/acm/contest/139/I 题意: 给出一个n(1≤n≤5e4)个字符的字符串s(si ∈ {a,b,c}),求最多可以从n*(n+1 ...
- 牛客网多校训练第一场 D - Two Graphs
链接: https://www.nowcoder.com/acm/contest/139/D 题意: 两个无向简单图都有n(1≤n≤8)个顶点,图G1有m1条边,图G2有m2条边,问G2有多少个子图与 ...
- HDU 4869 Turn the pokers (2014多校联合训练第一场1009) 解题报告(维护区间 + 组合数)
Turn the pokers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 2015多校联合训练第一场Tricks Device(hdu5294)
题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t 思路: 先跑一边最短路,记录最短路中最短的边数.总边数-最短边数就是第二个答案 第一个答案就是在最短路里 ...
- SDU暑假排位第一场 (Gym - 100889)
啊今天有点挂机啊 D题和队友暴力后发现一组数据跑得飞快 然后遇上1e5组数据就没了..... 然后我疯狂优化暴力 然后去世了 最后半小时F也没写出来 主要还是最后有点慌并且没有考虑清楚 导致情况越写越 ...
随机推荐
- python网络编程-paramiko模块
paramiko模块 该模块基于SSH用于连接远程服务器并执行相关操作 参考文档 SSHClient 用于连接远程服务器并执行命令 import paramiko #创建SSH对象 ssh = par ...
- 开源时序服务器influxdb使用
文档 https://influxdb.com/docs/v0.9/introduction/overview.html 配置文件 /etc/opt/influxdb/influxdb.conf re ...
- git 因线上分支名重复导致无法拉取代码
有时 git pull 或 git fetch 时发现 git 报了个异常,说法像是无法将线上某个分支与本地分支合并,由于分支是...(很长的hash)但是分支却是...(很长的hash) 仔细查查后 ...
- linux基础命令-mkdir/tree/rmdir
命令行的展开 ~: 展开为用户的主目录 ~USERNAME: 展开为指定用户的主目录 {}:可承载一个以逗号分隔的列表,并将其展开为多个路径 [root@host01 tmp]# mkdir -vp ...
- CAD出现向程序发送命令时出现问题提示解决方法分享
大家有没有遇到在使用cad打开图纸的时候提示向程序发送命令时出现错误的情况呢,如果你在使用cad的时候出现了这个提示,是由于软件的兼容性出现了问题,那么该怎么办呢,下面小编就给大家带来cad打开图纸提 ...
- GNU Nano编辑器
^表示 control建 ^X 退出 nano ^O 保存文件 ^R 插入其他文件内容至光标位置 ^W 查找字符串 ^Y 跳至前一屏 ^V 跳至后一屏 ^K 剪切光标所在行并保存到剪贴板,或剪切选中内 ...
- 22 Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1->2-&g ...
- 空间最短路径,BFS(POJ3278)
题目链接:http://poj.org/problem?id=3278 #include <cstdio> #include <queue> #include <stri ...
- vuejs非父子组件传值
当父组件要给孙子,或者孙子与孙子要传值的时候怎么传,一层一层传太麻烦了,vuejs提供了一中模式叫发布订阅模式(观察者模式,bus,总线)来处理非父子组件间的传值 <div id='root'& ...
- redis 对cmd的操作
这个是原子递增的知识点: 关于list部分: 利用lpush命令, rpush命令, lrange命令,对列表操作 此前 我已经 在列表(list)中 插入了 部分 元素了 关于集合set 部分 首先 ...