プロジェクトオイラー問126

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20126
Problem 126 「直方体層」 †
層のブロック数を数える問題。

解法
3軸のうちXY平面で3つに切断して集計すると計算式を立てやすいです。
数式が複雑になったので小さいほうから全探索しました。

#include <iostream>
#include <queue>
#include<stdio.h>
using namespace std;

struct E{
	int w,d,h,a,mode;
	int calc()const{
		int a1=2*d*w+2*w*h+4*(a-1)*w;
		int a2=2*(h*d+2*d*(a-1)+2*h*(a-1)+2*(a-1)*(a-2));
		return a1+a2;
	}
    bool operator<(const E& e)const{
		return calc()>e.calc();
	}
};

int main() {
	// your code goes here
	std::priority_queue<E> pq;
	E e1;
	e1.w=e1.d=e1.h=e1.a=1;
	e1.mode=0;
	pq.push(e1);
	int now=e1.calc();
	int count=1;
	while(pq.empty()==false){
		e1=pq.top();
		pq.pop();
		if(e1.calc()>now){
			if(count==1000)break;
			now=e1.calc();
			count=1;
		}else{
			count++;
		}
		e1.a++;
		pq.push(e1);
		e1.a--;
		//printf("(%d %d %d %d %d)",e1.h,e1.d,e1.w,e1.a,now);
		if(e1.a>1)continue;
		if(e1.mode==0){
			e1.w++;
 			e1.d=e1.h=1;
			e1.mode=0;
			pq.push(e1);
			e1.d=2;
			e1.h=1;
			e1.mode=1;
			pq.push(e1);
		}else if(e1.mode==1){
			if(e1.w>=e1.d+1){
				E e2=e1;
 				e2.mode=1;
			e2.h=1;
 				e2.d++;
				pq.push(e2);	
			}
			if(e1.h==1){
				E e2=e1;
				e2.mode=2;
 				e2.h=2;
				pq.push(e2);
			}	
		}else{
 			if(e1.d>=e1.h+1){
				e1.h++;
				pq.push(e1);
			}
		}
 	}
	cout<<now;
 	return 0;
 }
最終更新:2015年01月07日 12:05