zoukankan      html  css  js  c++  java
  • 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("
    ");
    	}
    

    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("
    ");
    	}
    		
    	return 0;
    }
    
    
    

    EdisonBa

    2020.8.4

  • 相关阅读:
    H5移动前端完美布局之-margin百分比的使用
    javascript 一个关于时间排序的算法(一个页面多个倒计时排序)
    html5 getComputedStyle + resize 实现动态宽高度等比响应式页面设计
    Windows 下关于转码的函数
    项目编译完之后自动提交
    eclipse 包含头文件出错
    Eclipse 包含头文件 添加环境变量
    linux下mongodb程序和c++客户端的编译
    简单谈谈消息发送缓冲区
    epoll 性能分析(解决占用CPU 过高问题)2
  • 原文地址:https://www.cnblogs.com/EdisonBa/p/13435680.html
Copyright © 2011-2022 走看看