zoukankan      html  css  js  c++  java
  • Java实现蓝桥杯历届试题格子刷油漆

    问题描述
      X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆。

    你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但不能移动到较远的格子(因为油漆未干不能踩!)
      比如:a d b c e f 就是合格的刷漆顺序。
      c e f d a b 是另一种合适的方案。
      当已知 N 时,求总的方案数。当N较大时,结果会迅速增大,请把结果对 1000000007 (十亿零七) 取模。
    输入格式
      输入数据为一个正整数(不大于1000)
    输出格式
      输出数据为一个正整数。
    样例输入
    2
    样例输出
    24
    样例输入
    3
    样例输出
    96
    样例输入
    22
    样例输出
    359635897

    问题分析:

    首先,对这些墙刷油漆主要分为两大类:

    1.从最边缘的四个格子出发,然后遍历完所有格子;

    2:从中间的某个格子出发,先遍历完一边的格子,回到这个格子所对的格子,然后遍历另一边的格子。

    所以,我们不妨用两个数组来表示这两种情况:

    1.a[i]数组表示从最边缘的四个格子中某个出发,遍历完长度为i,个数为2i个格子的所有种类数;

    2.b[i]数组表示从除了最边缘的四个格子外的某个中间的格子出发,遍历完一边回到所对的格子;

    然后,我们来分别分析a[i]和b[i]两种不同的情况:

    1.a[i]第一种情况:先走这个格子(以左上角的格子为例)所对的下面的格子,然后从下面这个格子的位置出发,有两种走法,分别到第二列的两个格子,所以第一种情况有:

    2a[i-1]种;a[i]第二种情况:(举例)先从左上角的格子走到第二列某个格子,然后从第二列的格子出发,遍历完右面所有的格子,再回到第二列格子所对的格子,最后到第一列未遍历的格子,所以这种情况就是我们定义的b[i];a[i]第三种情况:就是遍历完一二列的所有格子,从第三列的格子出发,进行遍历。由于遍历完一二列的所有格子有四种情况,所以第三种情况为:4a[i-2];

    所以,a[i]=2a[i-1]+b[i]+4a[i-2];

    2.b[i]的情况:b[i]比较简单,只有两种情况,从同一行的格子出发,回到他所对的格子;或者从他对角的格子出发,回到他所对的格子。

    所以,b[i]=2*b[i-1];

    接下来,就是算总和:

    1.四个角:定义sun=4*a[n];

    2.设从第i列开始,则前面有i-1列,后面有n-i列。

    第i列有两个格子,这两个格子所表示的情况数是相同的,所以只需要讨论一个。

    然后,我们以第i列的上面的格子为例,先遍历他的左边,然后遍历右边。(回到他所对的格子,遍历右边时,又分为两种情况。从第i+1列上面的格子开始和从下面的格子开始)

    即b[i]2a[n-i],化简得:2*b[i-1]2a[n-i];

    同理得:先遍历右边,再遍历左边为:2*b[n-i]2a[i-1];

    然后又因为a[1]=1;a[2]=6;b[1]=1;

    import java.util.Scanner;
    
    
    public class 格子刷油漆 {
    	public static void main(String[] args) {
    		Scanner scan=new Scanner(System.in);
    		int n=scan.nextInt();
    		long a[]=new long[n+1];
    		long b[]=new long[n+1];
    		long sum;
    		b[1]=1;
    		for(int i=2;i<=n;i++){
    			b[i]=2*b[i-1]%1000000007;
    		}
    		a[1]=1;a[2]=6;
    		for(int i=3;i<=n;i++){
    			a[i]=(2*a[i-1]+b[i]+4*a[i-2])%1000000007;
    		}
    		sum=(4*a[n])%1000000007;
    		for(int i=2;i<n;i++){
    			sum+=((8*b[i-1]*a[n-i])%1000000007+(8*b[n-i]*a[i-1])%1000000007)%1000000007;//必须每个项都取余,防止有大于这个数的情况
    			sum%=1000000007;
    		}
    		System.out.println(sum);
    	}
    
    
    }
    
    

    到处转载只是为了给复习的人提供便利,看一个博主就能找到挺全的题和题解
    转自:https://blog.csdn.net/qq_22891105/article/details/51050565

  • 相关阅读:
    java之大文件断点续传
    Html5大文件断点续传
    前端js怎么实现大文件G级的断点续传(分块上传)和分段下载
    HTML5解决大文件断点续传
    完整版断点续传、秒传,支持超大大大文件_支持重定义文件名和路径
    起来吧!不要做奴隶的ITproject师们!
    Oracle PL/SQL 编程基础 实例
    C语言高速入门系列(八)
    POJ 3253-Fence Repair(堆)
    抽屉式导航可能减少产品一半的用户參与度
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13079006.html
Copyright © 2011-2022 走看看