路灯问题
人的天职在勇于探索真理。 ——哥白尼(波兰)
国庆长假期间,看到一条路上的路灯非常有趣,有红黄蓝三种颜色,依次排成一条线状。不禁联想到有个厂子的笔试题里面也有类似的场景,描述是这样子的,一条长长的公路上,分别挂有红黄蓝三种颜色的装饰灯,排列规则如图所示:(这里用三角形代表红灯,用正方形代表黄灯,用圆形代表蓝灯)
假设公路无限长,灯按照以上这种规律排列下去,要求程序计算每输入一个整数n,就能输出第n个位置的路灯颜色(图案)。这样的场景下,如果用数学的方法来解决,肯定要涉及到数列的求和,计算起来还是比较费劲的,用计算机帮我们实现计算,那就相当的快了。
随手写了个程序,跑了一下,能行:
package math;
import org.junit.Test;
/**
* 该类为按规律输出图形的实现
* @author jsyuger
* 有以下规律图形:
* △ □ ○ △ △ □ □ ○ ○ △ △ △ □ □ □ ○ ○ ○ ......
* 输出第n个图形的图案
*/
public class PrintRegular {
/**
* 输入第n个位置,返回第n个位置的图案
* @param n
* @return
*/
public String printRegular(int n) {
int m = 0 ; /** 用于图形的总计数 **/
String type = "△" ; /** 初始化返回的图案类型 **/
for(int i=1 ; i<=n && m<=n ; i++) {
for(int a=1;a<=i;a++) { //用于循环打印三角形
//System.out.print("△"); //用于测试
m++; //每打印一个三角形计数器加1
if(m==n) { //当达到第n个的时候,返回图案类型,跳出循环
type = "△";
break;
}
}
for(int b=1;b<=i;b++) {
//System.out.print("□"); //用于测试
m++;
if(m==n) {
type = "□";
break;
}
}
for(int c=1;c<=i;c++) {
//System.out.print("○"); //用于测试
m++;
if(m==n) {
type = "○";
break;
}
}
}
return type ;
}
@Test
/**
* 测试方法:输出前18个图案
*/
public void test() {
for(int i=1;i<=18;i++)
System.out.print(printRegular(i));
}
}
控制台输出结果:
△□○△△□□○○△△△□□□○○○
以上路灯问题是简单一维控制位置,即路灯只有形状(或颜色)这一单一变量的控制。拓展一下,假设该公路上的灯是按照下面的方式进行排列的,即按照三角形、正方形、圆形顺序,颜色则按照红黄蓝绿的顺序来排列:
此时,路灯则有两个变量来控制,即颜色和形状。要求程序输出第n个位置的图案以及颜色。
随手改了下上面的程序,跑了一下,也能行:
package math;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
/**
* 该类为按规律输出图形的实现
* @author jsyuger
* 有以下规律图形:
* △ □ ○ △ △ □ □ ○ ○ △ △ △ □ □ □ ○ ○ ○ ......
* 输出第n个图形的图案
*/
public class PrintRegular {
/**
* 输入第n个位置,返回第n个位置的图案和颜色
* @param n
* @return
*/
public Map<String,String> printRegular(int n) {
Map<String,String> hashMap =new HashMap<String,String>(); //用于存放结果(形状->颜色)
int m = 0 ; /** 用于图形的总计数 **/
String type = "△" ; /** 初始化返回的图案类型 **/
String color = "red"; /** 初始化返回的图案颜色 **/
for(int i=1 ; i<=n && m<=n ; i++) {
for(int a=1;a<=i;a++) { //用于循环打印三角形
m++; //每打印一个三角形计数器加1
if(m==n) { //当达到第n个的时候,返回图案类型,跳出循环
type = "△";
break;
}
}
for(int b=1;b<=i;b++) {
m++;
if(m==n) {
type = "□";
break;
}
}
for(int c=1;c<=i;c++) {
m++;
if(m==n) {
type = "○";
break;
}
}
}
//获取颜色
int x = n%4 ;
switch(x) {
case(0) :
color = "green" ;
break;
case(1) :
color = "red";
break;
case(2) :
color = "yellow";
break;
case(3) :
color = "blue";
break;
}
//封装结果
hashMap.put(type, color);
return hashMap ;
}
@Test
/**
* 测试方法:输出第9个图案以及颜色
*/
public void test() {
System.out.print(printRegular(9));
}
}
控制台输出:
{○=red}
读者朋友们可尝试对路灯的变量添加多维控制,在计算机里面,每个维度都可以单独计算求值,除非是两个关联影响的变量。路灯问题实际上,是按照规律打印图案的基础问题的现实场景,按照一定的规律输出图案,可自行尝试编码实现。