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=233;
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[]={1,0,0,-1};
int addy[]={0,1,-1,0};

void show()
{
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<n;++j)
        {
            cout<<mapp[i][j];
            if(j == n-1)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<0||x>=n||y<0||y>=n)return false;
    if(mapp[x][y] != -1)return false;
    
    for(int i=0;i<4;++i)
    {
        int tx = x + addx[i];
        int ty = y + addy[i];
        if(tx<0||tx>=n||ty<0||ty>=n)continue;
        if(mapp[tx][ty] == -1)continue;
        bool succ = 0;
        for(int j=0;j<len;++j)
        {
            int tar = G[now][j];
            if(mapp[tx][ty] == tar)
            {
                succ = 1;
                break;
            }
        }if(!succ)return false;
    }return true;
}

void set_first(int now,int dep)
{
    int d1 = dep;
    int d2 = n-1-dep;
    int x[] = {d1,d1,d2,d2};
    int y[] = {d1,d2,d1,d2};
    for(int i=0;i<4;++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<0||x>=n||y<0||y>=n)return false;
    int d1 =dep;
    int d2 = n-1-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[4];
    for(int i=0;i<4;++i)
    {
        next_coors[i] = make_pair(x+addx[i],y+addy[i]);
    }
    int len = G[now].size();
    for(int i=0;i<len;++i)
    {
        int tar = G[now][i];
        if(coors[tar].first != -1)continue;
        if(du[tar]==4)continue;
        for(int j=0;j<4;++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=0;i<len;++i)
    {
        int now = que[i];
        int len1 = G[now].size();
        for(int j = 0;j<len1;++j)
        {
            int tar = G[now][j];
            du[tar] -- ;
            if(du[tar] == 2)s_ele = tar;
        }
    }
}

void init()
{
    memset(mapp,-1,sizeof(mapp));
    int len = 2*n*n -2*n;
    for(int i=0;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=1;i<=len;++i)
    {
        coors[i] = make_pair(-1,-1);
        du[i] = G[i].size();
        if(du[i] == 2)s_ele = i;
    }
    int dep = 0;
    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 0;
}

 

posted @ 2018-07-29 02:09  六花的邪王真眼  阅读(137)  评论(0编辑  收藏  举报