※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

「オイラープロジェクト91~100」の編集履歴(バックアップ)一覧に戻る

オイラープロジェクト91~100 - (2012/09/05 (水) 10:26:39) の編集履歴(バックアップ)


問い91

xy平面上の0<=x<=50&&0<=y<=50の範囲で原点と整数座標2点で三角形を作るとき直角三角形はいくつ作ることが出来るか。

計算量の少ない解法を記述するのがめんどくさかったので手抜きでクリア。
全探索しても6250万通りと組み合わせ数が少ないので一瞬で計算が終わります。
多分この問題が出題された当時だと1分ルールは切れないのでしょうが今のパソコンでは一瞬ですね。


#include<stdio.h>
#include<algorithm>
int main(){
int a[3];
int size=50,ans=0;
for(int x1=0;x1<=size;x1++){
	for(int y1=0;y1<=size;y1++){
		if(x1==0&&y1==0)continue;
		for(int x2=0;x2<=size;x2++){
			for(int y2=0;y2<=size;y2++){
				if((x2==0&&y2==0)||(x2==x1&&y2==y1))continue;
				a[0]=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
				a[1]=x1*x1+y1*y1;
				a[2]=x2*x2+y2*y2;
				std::sort(a,a+3);
				if(a[0]+a[1]==a[2]){
					ans++;
				}
			}
		}
	}
}
printf("%d",ans/2);
}



問い92

各桁の2乗を足し合わせた数を求め、それを繰りかすと必ず1か89に到達する。
1000万以下で89に到達する数の個数を求めよ。


#include<stdio.h>
int memo[1000]={0};
int saiki(int n){
if(n==1||n==89){
	return n;
}
if(n<1000&&memo[n]!=0)return memo[n];
int next=0,m=n;
while(m!=0){
	next+=(m%10)*(m%10);
	m/=10;
}
m=saiki(next);
if(n<1000)memo[n]=m;
return m;
}
int main(){
int ans=0;
for(int i=1;i<10000000;i++){
	ans+=(saiki(i)==89);
}
printf("%d",ans);
}



問い97

28433×2^7830457+1は素数でありこれの下10ケタを答えよという問題。
Lispは苦手だけどLispでなかったらこんなに簡潔には書けない気もする。
Lisp様様って感じ(俺がヘボいだけかな)



(defvar mask 10000000000)
mask
(setq mask 10000000000)
10000000000
(defun saiki (n m all)
  (if (< 0 m)
      (if (= (mod m 2) 1) 
	  (saiki (mod (* n n) mask) (floor (/ m 2)) (mod (* all n) mask))
	(saiki (mod (* n n) mask) (floor (/ m 2)) all))
    all))
saiki
(mod (+ (* (saiki 2 7830457 1)  28433) 1) mask)





問い99

数万^数万乗形式の大きな数が1000行与えられるので一番大きな数字の書かれた行を探せという問題。
対数を使って計算すれば楽勝。
楽勝なんだけど、このコードで合格出来たけど一応1だけ数字が違うのきたら大小関係が判別できないはずだけどこれで合格でいいのかな?


#include<stdio.h>
#include<math.h>
int main(){
double a,b,c,myMax=0;
int ansNo;
for(int i=0;i<1000;i++){
	scanf("%lf,%lf",&a,&b);
	c=log(a)*b;
	printf("( %lf %lf)\n",log(a),b);
	if(c>myMax){
		myMax=c;
		ansNo=i+1;
	}
}
printf("%d\n",ansNo);
}