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

問81 A Symmetric Point

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0081
線対称な点を計算せよという問題。

解法
数学の歴史に変換や特定の条件を満たす点を求めるための計算式のリストをひたすら作るというものがありました。
線対称な点を求めるというのもその一つで行列演算にしたがえばいいだけです。
まあ線対称くらいなら行列演算してもいいけれど。
点によっては(19世紀の幾何の話を探るとあるのだけれど)x座標一つを求める式が30行くらいになる問題とかざら。
それくらいになると公式をプログラムに翻訳するだけでもバグが入りそうで怖い。

#include<stdio.h>
int main(){
 	double x1,y1,x2,y2,x3,y3,dx2,dy2,dx3,dy3,ab,ansX,ansY;
	while(scanf("%lf,%lf,%lf,%lf,%lf,%lf",&x1,&y1,&x2,&y2,&x3,&y3)!=EOF){
		dx2=x2-x1;
		dy2=y2-y1;
		dx3=x3-x1;
		dy3=y3-y1;
		ab=dx2*dx2+dy2*dy2;
 		ansX=(dx3*(dx2*dx2-dy2*dy2)+dy3*2*dx2*dy2)/ab;
		ansY=(dx3*2*dx2*dy2+dy3*(dy2*dy2-dx2*dx2))/ab;
		printf("%lf %lf\n",ansX+x1,ansY+y1);
	}
}




問82 Flying Jenny

メリーゴーランドを的確に止める問題。
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0082

解法
なんかはまった問題。
簡単なのに何でだろ?
自己分析するに、具体的思考力はないが、抽象的思考力はあるからだろう。
具体的に決まれば決まるほど逆に解けない。
たとえばこの問題が、毎回メリーゴーランドの形やサイズが変化する。
とかだったら一発で通った気がする。
抽象的でなく具体的に決まってるから解けない。

#include<stdio.h>
const int FJ[8]={4,1,4,1,2,1,2,1};

int main(){
	int ps[8];
	
	while(scanf("%d",&ps[0])!=EOF){
		int ans=ps[0],ansP=-1,ansNo=99999999;
 		for(int i=1;i<8;i++){
			scanf("%d",&ps[i]);
			ans+=ps[i];
		}
		for(int p=0;p<8;p++){
			int t=0;
 			int no=0;
			for(int j=0;j<8;j++){
				int a=FJ[(p+j)%8];
				t+=ps[j]-a>=0?ps[j]-a:0;
				no=no*10+a;
			}
			if(ans>t||(ans==t&&ansNo>no)){
 				ans=t;
				ansP=p;
				ansNo=no;
			}
		}
		for(int i=0;i<8;i++){
 			if(i>0)printf(" ");
			printf("%d",FJ[(ansP+i)%8]);
		}
		printf("\n");
	}
}





問83 Era Name Transformation


解法
前回の問題を教訓にこの問題はできるだけ抽象化して解いた。
具体的思考とは抽象的思考に現状認識にあうものを抽出したもので、抽象的思考とは具体的認識とそのほかのものの積み重ねから帰納演繹されえる。
このループのうち私は抽象的思考から現状を理解するために適したものを抽出する能力に問題があるのだろう。
抽象と具象の間の垣根はとても薄いように思える。
そもそも垣根などないのではないだろうか?

#include<stdio.h> 

const int years[4]={1868,1912,1926,1989};
const int mons[4]={9,7,12,1};
const int days[4]={8,30,25,8};
const char names[5][10]={"pre-meiji","meiji","taisho","showa","heisei"};
void change(int y,int m,int d){
	int p=0;
	for(int i=0;i<4;i++){
 
	if(years[i]<y)p++;
		if(years[i]==y){
			if(mons[i]<m)p++;
			else if(mons[i]==m){
				p+=(days[i]<=d);
			}
 		}
	}
	if(p==0)printf("%s\n",names[0]);
else printf("%s %d %d %d\n",names[p],y-years[p-1]+1,m,d);
}

int main(){
	int y,m,d;
	while(scanf("%d %d %d",&y,&m,&d)!=EOF){
 		change(y,m,d);
	}
}


問84 Search Engine

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0084
文章から単語を抽出する問題。
解法
読み取りの記法の問題なのでscanfのなかで全部解決します。

#include<stdio.h>
#include<string.h>

int main(){
 	char word[1025],spent[1025];
	scanf("%[., \n]",spent);
	int i=0;
	while(scanf("%[^,. \n]%[,. ]",word,spent)!=EOF){
		int len=strlen(word);
		if(len>2&&len<7){
			if(i==0)i=1;
			else printf(" ");
 			printf("%s",word);
		}
		if(scanf("%[\n]",spent)==EOF)break;
 		if(spent[0]=='\n')break;
	}
	printf("\n");
}





問85 Joseph's Potato

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0085
検索したらそのまま答えが出てきた。
動的計画法らしいのだがよくわからない。

#include<stdio.h>
int f(int n,int k){
	return n==1?0:(f(n-1,k)+k)%n;
}
int main(){
	int n,k;
	while(1){
 		scanf("%d %d",&n,&k);
		if((n|k)==0)break;
		printf("%d\n",f(n,k)+1);
	}
}