EJOI2017-骆驼

Posted kalginamiemeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EJOI2017-骆驼相关的知识,希望对你有一定的参考价值。

第一道构造题祭……

题目的提示很明显。

$N$是$5$的倍数,所以考虑分成$5 imes 5$小块连在一起。

首先通过打表证明,

小块里从任何一点出发,经过所有的格,从任一一点跳出,一定有这样的路径。

那么因为此题$spj$,所以只要想方设法构造出一种可行解就$OK$辣。

考虑块与块之间的关系。

(坑)

发现如果选择$(3,3)$点会很优,因为横着竖着走都可以,便于拐弯。

于是×了(学会偷懒,写函数!)

#include <iostream>
#include <cstring>
#include <cstdio>
#define L 1111
#define N 222
#define JST 0
#define JJK 1
#define OST 2
#define DOWN 3
#define UP 4
#define LEFT 5
#define RIGHT 6
using namespace std;
const int stdsq[7][5][5]={
	{
		{ 1, 8,16, 2, 7},
		{11,19, 5,10,18},
		{22,14, 0,21,15},
		{ 4, 9,17, 3, 6},
		{12,20,23,13, 0}
	},
	{
		{22, 3, 9,23, 2},
		{16,25,20,17, 7},
		{10,13, 1, 4,12},
		{21,18, 8,24,19},
		{15, 5,11,14, 6}
	},
	{
		{ 1,12, 5, 2,13},
		{ 7,18,15,10,19},
		{23, 3, 0,22, 4},
		{16,11, 6,17,14},
		{ 8,21,24, 9,20}
	},
	{
		{ 6,22,14, 7, 2},
		{19, 9, 4,20,12},
		{24,16, 1,23,15},
		{ 5,21,13, 8, 3},
		{18,10,25,17,11}
	},
	{
		{ 9,22,25, 8, 2},
		{17,12, 4,20,15},
		{24, 7, 1,23, 6},
		{10,21,16,11, 3},
		{18,13, 5,19,14}
	},
	{
		{ 9,17,24, 8, 2},
		{22,12, 4,19,13},
		{25, 7, 1,16, 6},
		{10,18,23,11, 3},
		{21,15, 5,20,14}
	},
	{
		{22,14, 7,23, 2},
		{ 9,19, 4,12,18},
		{ 6,24, 1,15,25},
		{21,13, 8,20, 3},
		{10,16, 5,11,17}
	}
};
int ans[L][L],len,bn;
struct Fivesq{
	int id,addup;
	void update(const int x,const int y){
		for(int i=0;i<5;i++)
			for(int j=0;j<5;j++)
				ans[x+i][y+j]=stdsq[id][i][j]+addup;
	}
};
Fivesq mp[N][N];
void set(int li,int f,int t,int val){
	for(int i=f;i<=t;i++)
		mp[li][i].id=val;
}
void search(int x,int y,const int lsv){
	int val=lsv;
	while(mp[x][y].id!=JST 			&&mp[x][y].id!=JJK 				&&mp[x][y].id!=OST){
				//cout<<x<<" "<<y<<" "<<mp[x][y].id<<endl;
		mp[x][y].addup=val;
		val+=25;
		if(mp[x][y].id==UP   )x--;
		else if(mp[x][y].id==DOWN )x++;
		else if(mp[x][y].id==LEFT )y--;
		else if(mp[x][y].id==RIGHT)y++;
	}
	if(mp[x][y].id==JJK){
		mp[x][y].addup=val;
	}
}
int main(){
	scanf("%d",&len);
	if(len==5){
		puts("1 14 7 4 15
9 22 17 12 23 
19 5 25 20 6
2 13 8 3 16 
10 21 18 11 24");
		return 0;
	}
	bn=len/5;
	if(bn&1){
		mp[0][0].id=JST;
		mp[1][1].id=JJK;
		for(int i=1;i<bn;i++){
			if(i&1)mp[0][i].id=DOWN;
			else   mp[0][i].id=LEFT;
		}
		for(int i=2;i<bn;i++){
			if(i&1)mp[1][i].id=LEFT;
			else   mp[1][i].id=UP;
		}
		for(int i=1;i<bn;i++)
			mp[i][0].id=DOWN;
		mp[bn-1][0].id=RIGHT;
		for(int i=2;i<bn;i++){
			if(i&1){
				set(i,1,bn-1,LEFT);
				mp[i][1].id=UP;
			}
			else{
				set(i,1,bn-1,RIGHT);
				mp[i][bn-1].id=UP;
			}
		}
		search(1,0,23);
		for(int i=0;i<bn;i++)
			for(int j=0;j<bn;j++)
				mp[i][j].update(i*5,j*5);
		ans[2][2]=len*len;
		ans[4][4]=len*len-1;
	}
	else{
		mp[0][0].id=OST;
		for(int i=1;i<bn;i++)
			mp[i][0].id=DOWN;
		mp[bn-1][0].id=RIGHT;
		set(0,1,bn-1,LEFT);
		for(int i=1;i<bn;i++){
			if(i&1){
				set(i,1,bn-1,RIGHT);
				mp[i][bn-1].id=UP;
			}
			else{
				set(i,1,bn-1,LEFT);
				mp[i][1].id=UP;
			}
		}
		/*for(int i=0;i<bn;i++){
			for(int j=0;j<bn;j++){
				printf("%d ",mp[i][j].id);
			}puts("");
		}*/
		search(1,0,24);
		for(int i=0;i<bn;i++)
			for(int j=0;j<bn;j++)
				mp[i][j].update(i*5,j*5);
		ans[2][2]=len*len;
	}
	for(int i=0;i<len;i++){
		for(int j=0;j<len;j++){
			printf("%d ",ans[i][j]);
		}puts("");
	}
}

 

以上是关于EJOI2017-骆驼的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #500 (Div. 2) [based on EJOI]

Luogu P6303 [eJOI2018]AB 串 题解

Luogu P6303 [eJOI2018]AB 串 题解

P5089 [eJOI2018]元素周期表(并查集)

驼峰命名法---2017-03-28

Rabbitmq 骆驼弹簧靴自动配置