ツムラ_メモ

大失敗を繰り返す。

サーバー構築ですか?

技術英語では主にアルゴリズムに関して突っ込まれた。
やはりと言うべきか、他にもっと良さそうなのがあるんじゃねーっていう。
しかし、これも予測出来た事だが、なかなか見つからない。
誰か良い解法があるなら教えて欲しいが、まぁ自分でちょっと粘ってみるかな。

/* ProblemA.c */
#include<stdio.h>
#include<stdlib.h>

/* 石の番号と次の石へのポインタを持つ構造体 */
typedef struct stone{
	int number;
	struct stone *next;
}Stone;

Stone *RemoveStone(Stone *pos,int k);
int main(void){
	FILE *fpi,*fpo;	//fpi 読み込むファイル fpo 書き込むファイル
	int n,k,m,cnt;	
	int StoneSize = sizeof(Stone); //構造体Stoneのサイズを保存
	Stone *root,*pos;

	/* 入出力の設定 */
	if((fpi=fopen("B.in","r"))==NULL){
		fprintf(stderr,"NO:A.in");
		exit(-1);
	}
	if((fpo=fopen("Result.txt","w"))==NULL){
		fprintf(stderr,"ERROR:CAN'T MAKE OUTPUT FILE");
		exit(-2);
	}
	
	root=pos=malloc(StoneSize); //rootとposを1番の石に設定
	while(fscanf(fpi,"%d %d %d",&n,&k,&m)!=EOF){	
		if(n==0 && k==0 && m==0)
			break;	// n k m が0の場合終了
		m--;	
		
		/* n個になるまで石を増やす */
		for(cnt=1;cnt<n;cnt++){
			pos->number=cnt;
			pos->next=malloc(StoneSize);
			pos=pos->next;
		}
		
		/* n番目の石の次の石を1番目の石に設定 */
		pos->number=cnt;
		pos->next=root;
		
		/* 最初に取る石が1番目の石の場合はn番目の石からのポインタを変更する必要があるので、
		   n番目の石のアドレスを渡す。
		   それ以外の場合は1番目の石から順に、m番目の石の一つ手前の石へのポインタを探し、
		   そのアドレスを渡す。
		*/
		if(m!=0){
			pos=root;
			while(pos->number<m)
				pos=pos->next; 
			}
			
		/* RemoveStoneを呼び出し、戻り値の最後に残った石のアドレスをrootとposに代入する */	
		fprintf(fpo,"%d\n",(root=pos=RemoveStone(pos,k))->number);
	}
	free(root);	fclose(fpi); fclose(fpo);
	return 0;
}

/* RemoveStone()
   m番目の石の一つ前の石へのポインタとkを引数に呼び出され、
   最後に残る石へのポインタを返す関数
*/   
Stone *RemoveStone(Stone *pos,int k){
	int cnt;
	Stone *DeleteTarget;
	
	/* 1回目のwhile文でm番目の石が取り除かれる
	   その後のfor文でk個次の石を探し、その石を取り除く
	   最後の1個になったらwhile文を抜ける
	*/
	while(pos->next!=pos){
		DeleteTarget=pos->next;
		pos->next=DeleteTarget->next;
		free(DeleteTarget);
		for(cnt=1;cnt<k;cnt++)
			pos=pos->next;
	}
	return pos;
}