思路:递归构造四分树,然后递归相加四分树,最后递归统计每层的黑色格子数
java实现,输入略,代码比较长而且累赘
package test;
import java.util.Scanner;
public class Test{
static Scanner sc = new Scanner(System.in);
static String line;
static class Node{
int value;
Node[] next;
@Override
public String toString() {
if(next==null){
return value+",";
}else{
return value+":"+next[0]+next[1]+next[2]+next[3];
}
}
}
/**
* 递归构造四分树
* @param root
* @param start
* @param arr
* @return
*/
static int build(Node root,int start,char[] arr){
int count = -1;
while(count++<3&&start<arr.length){
Node n = new Node();
root.next[count] = n;
if(arr[start]=='p'){
n.value = 2;
n.next = new Node[4];
start = build(n,++start,arr);
}else if(arr[start]=='f'){
n.value = 1;
start++;
}else if(arr[start]=='e'){
n.value = 0;
start++;
}
}
return start;
}
/**
* 四分树root=四分树roo1+四分树root2
* @param root
* @param root1
* @param root2
*/
static void add(Node root,Node root1,Node root2){
if(root1.value==1 || root2.value==1){
root.value = 1;
return;
}else if(root1.value==2 && root2.value==0){
root.value = 2;
root.next = root1.next;
}else if(root1.value==0 && root2.value==2){
root.value = 2;
root.next = root2.next;
}else if(root1.value==0 && root2.value==0){
root.value = 0;
return;
}else if(root1.value==2 && root2.value==2){
root.next = new Node[4];
for(int i=0;i<4;i++){
root.next[i] = new Node();
add(root.next[i],root1.next[i],root2.next[i]);
}
}
}
static int[] re = new int[100];
static int sum = 0;
/**
* 递归计算每层的黑色
* 利用re数组的index标示第几层黑色的个数
* @param root
*/
static void count(Node root){
if(root.next!=null){
for(Node n:root.next){
if(n.value==1){
re[sum]++;
}else if(n.value==2){
sum++;
count(n);
sum--;
}
}
}
}
public static void main(String[] args) {
String str1 = "peeefpffeefe";
Node root1 = new Node();
root1.next = new Node[4];
root1.value = 2;
build(root1,0,str1.toCharArray());
System.out.println(root1);
String str2 = "efepeefe";
Node root2 = new Node();
root2.next = new Node[4];
root2.value = 2;
build(root2,0,str2.toCharArray());
System.out.println(root2);
Node root = new Node();
root.value = 2;
add(root,root1,root2);
System.out.println(root);
count(root);
int allblack = 0;
int i = 0;
/**
* 从上到下,如果有下层,则原黑色个数乘以4,再加上下层黑色
*/
while(re[i]!=0){
allblack = re[i] + allblack*4;
i++;
}
System.out.println(allblack*64);
}
}
另外一种思路更加直观:
package test;
import java.util.Scanner;
public class Test{
static Scanner sc = new Scanner(System.in);
static String line;
static int[][] buf = new int[32][32];
static int p = 0,cnt=0;//当前字符位置
/**
* 画出(r,c)为左上角,边长为w的四分树
* @param s
* @param r
* @param c
* @param w
*/
static void draw(char[] s,int r,int c,int w){
char ch = s[p++];
if(ch=='p'){
draw(s,r,c,w/2);
draw(s,r+w/2,c,w/2);
draw(s,r,c+w/2,w/2);
draw(s,r+w/2,c+w/2,w/2);
}else if(ch=='f'){//如果是黑色,则子树都是黑色
for(int i=r;i<r+w;i++){
for(int j=c;j<c+w;j++){
if(buf[i][j]==0){
buf[i][j]=1;
cnt++;
}
}
}
}
}
public static void main(String[] args) {
p=0;
String str1 = "ppeeefpffeefe";
draw(str1.toCharArray(), 0, 0, 32);
p=0;
String str2 = "pefepeefe";
draw(str2.toCharArray(), 0, 0, 32);
System.out.println(cnt);
}
}