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

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2081
Problem 81 「経路の和:2方向」 †
数字の書かれたマス目を右か下へ移動しながら移動経路の数字の総和をとり、それの最小値を求める問題。

解法
貪欲法で十分です。
コードが長いです、もっと短く書けないかな。

#include<stdio.h>
#include<vector>
#include<queue>


struct E{
 	int x,y,sum;
	bool operator<(const E& e)const{
		return sum>e.sum;
	}
};

int main(){

	FILE *fp;
	char *fname = "pe81.txt";
	
	fp = fopen( fname, "r" );
	if( fp == NULL ){
		printf( "%sファイルが開けません\n", fname );
		return -1;
	}
	int n;
	char c;
	int row=0;
	std::vector<std::vector<int> > mat,memo;
	std::vector<int> vec;
	mat.push_back(vec);
	memo.push_back(vec);
	while(fscanf(fp,"%d%c",&n,&c)!=EOF){
		mat[row].push_back(n);
		memo[row].push_back(-1);
		if(c=='\n'){
			mat.push_back(vec);
			memo.push_back(vec);
			row++;
		}
	}
	fclose(fp);
	int w=mat[0].size();
	int h=mat.size();
	std::priority_queue<E> pq;
	E e1,e2;
	e1.x=e1.y=0;
	e1.sum=mat[0][0];
 	pq.push(e1);
	while(pq.empty()==false){
		e1=pq.top();
		pq.pop();
 		if((e1.x==w-1)&&(e1.y==h-1))break;
		e2=e1;
		e2.x++;
		if(e2.x<w){
			e2.sum+=mat[e2.y][e2.x];
			if(memo[e2.y][e2.x]==-1 || memo[e2.y][e2.x]>e2.sum){
				memo[e2.y][e2.x]=e2.sum;
				pq.push(e2);
			}
		}
		e2=e1;
		e2.y++;
 		if(e2.y<h){
			e2.sum+=mat[e2.y][e2.x];
			if(memo[e2.y][e2.x]==-1 || memo[e2.y][e2.x]>e2.sum){
				memo[e2.y][e2.x]=e2.sum;
				pq.push(e2);
			}
		}
 	}
	printf("%d\n",e1.sum);
}
最終更新:2014年12月13日 13:58