Cod sursa(job #638473)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 20 noiembrie 2011 21:41:53
Problema Portal3 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include<fstream>
#include<cmath>
#include<cstring>
using namespace std;
int T,n,m,p[7],c[7],v[8];
long long d[8][8],distmin,C[4];
struct Pozitie{int x,y;};
Pozitie P[7];
bool uz[8];

inline int Abs(int a)
{
	if(a>=0)
		return a;
	return -a;
}

inline long long Dist(int a,int b,int c,int d)
{
	return (long long)(Abs(a-c)+Abs(b-d));
}

inline long long Min(long long a,long long b)
{
	if(b<a)
		return b;
	return a;
}

inline void Prelucrare(int nr)
{
	short i;
	long long dist;
	dist=d[0][v[1]];
	for(i=1;i<nr;i++)
		dist+=Min(Min(Dist(P[v[i]].x,P[v[i]].y,P[v[i+1]].x,P[v[i+1]].y),Dist(P[v[i]].x,P[v[i]].y,P[p[v[i+1]]].x,P[p[v[i+1]]].y)+C[c[v[i+1]]]),Min(Dist(P[p[v[i]]].x,P[p[v[i]]].y,P[v[i+1]].x,P[v[i+1]].y)+C[c[v[i]]],Dist(P[p[v[i]]].x,P[p[v[i]]].y,P[p[v[i+1]]].x,P[p[v[i+1]]].y)+C[c[v[i]]]+C[c[v[i+1]]]));
	dist+=d[v[nr]][7];
	distmin=Min(dist,distmin);
}

inline void Back(int k)
{
	if(k!=1)
		Prelucrare(k-1);
	if(k<4)
	{
		short i;
		for(i=1;i<7;i++)
		{
			if(!uz[i])
			{
				v[k]=i;
				uz[i]=true;
				Back(k+1);
				uz[i]=false;
			}
		}
	}
}

inline void Rezolvare()
{
	short i;
	d[0][7]=d[7][0]=Dist(0,0,n,m);
	for(i=1;i<7;i++)
	{
		d[0][i]=d[i][0]=Dist(0,0,P[i].x,P[i].y);
		d[i][7]=d[7][i]=Dist(P[i].x,P[i].y,n,m);
	}
	for(i=1;i<7;i++)
	{
		d[0][i]=d[i][0]=Min(d[0][i],d[0][p[i]]+C[c[i]]);
		d[7][i]=d[i][7]=Min(d[7][i],d[7][p[i]]+C[c[i]]);
	}
	distmin=d[0][7];
	Back(1);
}

int main()
{
	int t;
	ifstream fin("portal3.in");
	ofstream fout("portal3.out");
	fin>>T;
	p[1]=2; p[2]=1; c[1]=c[2]=1;
	p[3]=4; p[4]=3; c[3]=c[4]=2;
	p[5]=6; p[6]=5; c[5]=c[6]=3;
	for(t=0;t<T;t++)
	{
		fin>>n>>m;
		fin>>P[1].x>>P[1].y>>P[2].x>>P[2].y>>C[1];
		fin>>P[3].x>>P[3].y>>P[4].x>>P[4].y>>C[2];
		fin>>P[5].x>>P[5].y>>P[6].x>>P[6].y>>C[3];
		Rezolvare();
		fout<<distmin<<"\n";
		memset(d,0,sizeof(d));
	}
	fin.close();
	fout.close();
	return 0;
}