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

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20128
Problem 128 「六角形タイルの差分」 †


辺上の数字は隣接する2つは2差。
隣接する4つのうち外と内の2つ。
外の2つは片方が素数差になれば片方は素数差にならない。
うちの2つも同様。
より辺は素数差にならない。

6角形の点上と六角形の周回の一番最後が条件を満たす可能性がある。


後は規則性を見つけて実装ゲーム。
答えがintを越える点に注意。


#include<stdio.h>
#include<iostream>
bool isP(__int64 n){
	if(n<0)n=-n;
	for(__int64 i=2;i*i<=n;i++){
		if(n%i==0)return false;
	}
	return true;
}
 
__int64 main(){
	__int64 d=2;
	__int64 c=2;
	__int64 s=8;
	__int64 ans=0;
	const __int64 last=2000;
	while(1){
		//上
 		__int64 n1=s+6*d+1;
		__int64 n2=s+6*d-1;
		__int64 n3=s+6*d+6*(d+1)-1;
		if(isP(s-n1)+isP(s-n2)+isP(s-n3)==3){
			c++;
		}
		if(last==c){
			ans=s;
			break;
		}
 		n1=s+d*6-1;
		n2=n1+2;
		n3=s-(d-1)*6;
		for(__int64 i=1;i<=5;i++){
			n1+=d+1;
			n2+=d+1;
			n3+=(d-1);
			s+=d;
			
			if(isP(s-n1)+isP(s-n2)+isP(s-n3)==3){
 				c++;
			}
			if(last==c){
				
				ans=s;
				break;
			}
		}
 		
		
		if(last==c)break;
		s+=d;
		d++;
		
		__int64 s0=s-1;
 		__int64 a0=s-6*(d-1);
		__int64 a1=a0-6*(d-2);
		__int64 a2=a0-1;
		__int64 a3=s+6*d-1;
		__int64 a4=a3-1;
		//pr__int64f("a=%d %d %d %d %d %d\n",s0,a0,a1,a2,a3,a4);
		if(isP(s0-a0)+isP(s0-a1)+isP(s0-a2)+isP(s0-a3)+isP(s0-a4)==3){
			c++;
		}
		if(last==c){
			ans=s0;
			break;
		}
	}
	std::cout<<ans<<"\n";
}
最終更新:2016年01月23日 08:31