1. 程式人生 > 實用技巧 >CF45J Planting Trees 題解

CF45J Planting Trees 題解

CF45J Planting Trees 題解

題目描述

Vasya is a Greencode wildlife preservation society proponent. One day he found an empty field nobody owned, divided it into *n *× m squares and decided to plant a forest there. Vasya will plant nm trees of all different heights from 11 to nm . For his forest to look more natural he wants any two trees growing in the side neighbouring squares to have the absolute value of difference in heights to be strictly more than 1. Help Vasya: make the plan of the forest planting for which this condition is fulfilled.

輸入格式

The first line contains two space-separated integers n and m ( 1<=n,m<=1001<=n,m<=100 ) — the number of rows and columns on Vasya's field

輸出格式

If there's no solution, print -1. Otherwise, print n lines containing m numbers each — the trees' planting plan. In every square of the plan the height of a tree that should be planted on this square should be written. If there are several solutions to that problem, print any of them.

題意翻譯

Vasya是greencode野生動物保護協會的支持者。

有一天他找到了一個空地,他把它分成了 nm 個方格並決定在上邊種出一個森林。Vasya將要種 nm 棵高度從 1 到 nm 的樹,並且高度兩兩不同。

為了讓他的森林看起來更加的自然,他希望任意兩顆四聯通相鄰的樹高度差的絕對值嚴格大於1。請幫助Vasya制定森林的種植計劃。無解輸出 -1,多解輸出任意一種方案。

感謝@MloVtry 提供的翻譯

輸入輸出樣例

輸入 #1

2 3

輸出 #1

3 6 2
5 1 4

輸入 #2

2 1

輸出 #2

-1

題解

​ 我們先從最小的數字開始,比如說:n=1 , m=1時:

​ 顯然,答案是1.

​ 根據題意,我們可以模擬出不符合條件的情況:

​ n=1 , m=2;

​ n=1 , m=3;

​ n=2 , m=2;

​ n=2 , m=1

​ n=3 , m=1;

​ 根據觀察,這5種情況都有一個共同的特點,就是(n+m)<5 .

​ 那麼我們可以特判這幾種情況:

	if(n==1 && m==1)
	{
		printf("1");
		return 0;
	}
	if(n+m<5)
	{
		printf("-1");
		return 0;
	}

​ 剩下的情況呢,我們可以通過奇偶性將最大最小的數交叉填寫。

​ 因為題目中說任意兩顆四聯通相鄰的樹高度差的絕對值嚴格大於1,那麼我們儘可能讓相鄰的數同為奇數(或偶數)。也就是通過奇偶性來分開種樹。

​ 在此,我們可以找兩個數。一個為較小的數(l),另一個為較大的數(r)。

​ 答案中每個數的範圍在1~m*n中。

​ 為了讓答案分配得更合理,我們可以取一箇中間值放在答案中矩陣的左上角。把這個值賦給大數(r)。

\[r=\frac{n*m}{2} + 1; \]

然後交叉填寫:

前半部分:

\[1 → \frac{n*m}{2} \]

後半部分:

\[\frac{n*m}{2}+1 → n*m \]

交叉填寫程式碼:

	r=n*m/2 + 1;
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			if((i+j)%2==0)	
			{
				printf("%lld ",r);
				r++;	
			}
			else 
			{
				printf("%lld ",l);
				l++;
			}
		}		
		printf("\n");
	}

AC程式碼

/*---------------------------------
 *Title number:清北學堂 / Luogu
 *Creation date: 2020-08-04

 *Author: EdisonBa
 *-------------------------------*/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;

inline ll read(){
	ll f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}

ll n,m,l=1,r;
ll a[100][100];

int main()
{
	scanf("%lld%lld",&n,&m);
	if(n==1 && m==1)
	{
		printf("1");
		return 0;
	}
	if(n+m<5)
	{
		printf("-1");
		return 0;
	}
	r=n*m/2 + 1;
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			if((i+j)%2==0)	
			{
				printf("%lld ",r);
				r++;	
			}
			else 
			{
				printf("%lld ",l);
				l++;
			}
		}		
		printf("\n");
	}
		
	return 0;
}


EdisonBa

2020.8.4