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

教科書の公式を変形すると内部の点個数をPとすると
2P=(b+d)(a+c)+2-(gcd(a,b)+gcd(b,c)+gcd(c,d)+gcd(d,a))だけれど。
ABCを全部求めてACDをそれに対する追補として求めれば計算量落ちるな。
と思ったが。
m=100だったので機械的に解いた。
何だろうこの問題。
プロジェクトオイラーの最近の問題の中でも驚異的に優しい。
コード記述時間入れて15分で解けた。


#include <iostream>
#include <set>
using namespace std;

const int LIMIT=100;
int gcdMemo[LIMIT+1][LIMIT+1];

int gcd ( int a, int b )
{
  int c;
  while ( a != 0 ) {
     c = a; a = b%a;  b = c;
  }
  return b;
}


int main() {
	// your code goes here
	std::set<int> hit;
	for(int p=1;p<=300;p++){
		hit.insert(p*p*2);
	}
	for(int a=1;a<=LIMIT;a++){
		for(int b=1;b<=LIMIT;b++){
			gcdMemo[a][b]=gcd(a,b);
		}
	}
	
 	long long int ans=0;
	for(int a=1;a<=LIMIT;a++){
		for(int b=1;b<=LIMIT;b++){
			for(int c=1;c<=LIMIT;c++){
				for(int d=1;d<=LIMIT;d++){
					int s=(a+c)*(b+d)+2-gcdMemo[a][b]-gcdMemo[b][c]-gcdMemo[c][d]-gcdMemo[d][a];
					if(hit.find(s)!=hit.end()){
						ans++;
					}
				}
			}
		}
	}
	std::cout<<ans;
	return 0;
}   
最終更新:2015年02月28日 16:57