Az alábbi letöltési lehetőségek közül választhatsz: (
segítség)
Típus: text/plain
Tartalmaz szöveget
Karakterkódolás: utf-8
Méret: 4 KB
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <cmath>
using namespace std;
#ifndef INFINITY
#include <limits>
#define INFINITY numeric_limits<float>::infinity()
#endif
#define MaxItems 15
#define MaxStores 50
typedef unsigned char byte;
typedef unsigned short int word;
typedef unsigned long int dword;
typedef unsigned long long int qword;
struct sStore {
int X, Y;
double Price[MaxItems];
word Items;
} Store[MaxStores];
struct sItem {
bool bPerishable;
string Name;
} Item[MaxItems];
int nItems, nStores, POG;
double State[MaxStores][1 << MaxItems];
word AllItems;
void ReadItemDatas (ifstream &, sItem &);
void ReadStoreDatas (ifstream &, sStore &);
double Dist (int, int, bool);
double BestPrice (void);
double BestPrice (byte, word);
int main (int nArgs, char * Arg []) {
int N, I, J, K;
if (nArgs < 3)
return 1;
ifstream IF(Arg[1]);
ofstream OF(Arg[2]);
if (IF == NULL || OF == NULL) {
IF.close();
OF.close();
return 1;
}
IF >> N;
for (I = 0; I < N; I++) {
IF >> nItems >> nStores >> POG;
AllItems = (1 << nItems) - 1;
for (J = 0; J < nItems; J++)
ReadItemDatas(IF, Item[J]);
for (J = 0; J < nStores; J++)
ReadStoreDatas(IF, Store[J]);
OF << "Case #" << I + 1 << ": " << setprecision(7) << fixed << BestPrice() << endl;
}
IF.close();
OF.close();
return 0;
}
void ReadItemDatas (ifstream & IF, sItem & Item) {
IF >> Item.Name;
Item.bPerishable = Item.Name.find_first_of('!') < Item.Name.length();
if (Item.bPerishable)
Item.Name = Item.Name.substr(0, Item.Name.length() - 1);
}
void ReadStoreDatas (ifstream & IF, sStore & Store) {
int A, B, C, I;
string Items, IN_PR, IN;
int PR;
IF >> Store.X >> Store.Y;
getline(IF, Items);
A = Items.find_first_of(' ') + 1;
for (I = 0; I < nItems; I++)
Store.Price[I] = -1;
Store.Items = 0;
do {
B = Items.find_first_of(' ', A);
if (B >= Items.length())
B = Items.length();
IN_PR = Items.substr(A, B - A);
C = IN_PR.find_first_of(':');
IN = IN_PR.substr(0, C);
for (I = 0; I < nItems; I++)
if (Item[I].Name == IN) {
Store.Price[I] = atof(IN_PR.substr(C + 1).c_str());
Store.Items |= 1 << I;
}
A = B + 1;
} while (B < Items.length());
}
double Dist (int A, int B, bool bPerishable) {
return bPerishable ?
hypot(Store[A].X, Store[A].Y) + hypot(Store[B].X, Store[B].Y) :
hypot(Store[A].X - Store[B].X, Store[A].Y - Store[B].Y);
}
double BestPrice (void) {
double Q = INFINITY, P;
int I, J;
for (I = 0; I < nStores; I++)
for (J = 0; J < (1 << nItems); J++)
State[I][J] = 0;
for (I = 0; I < nStores; I++) {
P = hypot(Store[I].X, Store[I].Y) * POG + BestPrice(I, AllItems);
if (P < Q)
Q = P;
}
return Q;
}
double BestPrice (byte S, word Items) {
if (State[S][Items] != 0)
return State[S][Items];
word W = Items & Store[S].Items, X, It_;
int I;
bool bPer;
double Q = INFINITY, Price0, Price;
for (X = 1; X <= W; X++) {
if (X & ~W)
continue;
It_ = Items & ~X;
Price0 = 0;
bPer = false;
for (I = 0; I < nItems; I++)
if ((X >> I) & 1) {
Price0 += Store[S].Price[I];
bPer = bPer || Item[I].bPerishable;
}
if (It_ == 0) {
Price = Price0 + hypot(Store[S].X, Store[S].Y) * POG;
if (Price < Q)
Q = Price;
break;
}
for (I = 0; I < nStores; I++)
if (S != I && (Store[I].Items & It_)) {
Price = Price0 + Dist(S, I, bPer) * POG + BestPrice(I, It_);
if (Price < Q)
Q = Price;
}
}
return State[S][Items] = Q;
}