Informatika gyűjtemény

Egy szinttel feljebb mb_bevasarlas.cpp

2004050607080910

NézetNyomtat

mb_bevasarlas.cpp (Vissza)
Az alábbi letöltési lehetőségek közül választhatsz: (segítség)
Karakterkódolás:
Sortörés:
Típus: text/plain
Tartalmaz szöveget
Karakterkódolás: iso8859-2
Méret: 4 KB
#include <cstdio>
#include <iostream>
#include <string>
#include <math.h>

#define INF 1000000000

using namespace std;

int num_items, num_stores, price_of_gas;

struct store
{
    int id;
    int x, y;
    int item_count;
    int* items;
};

void beolvas(char* fnin, char* fnout);
double solve();
double min(store* s, unsigned int list, bool romlando, unsigned int beento);
double distance(store* s1, store* s2, bool home);

store* stores;
bool* items_romlando;

double*** dp;
double*** dp_distance;


int main()
{
    beolvas("D-large-practice.in", "D-large-practice.out");
    //beolvas("D-small-practice.in", "D-small-practice.out");

    cin.get();
    return 0;
}

double solve()
{
    dp = new double**[num_stores];
    for (int i = 0; i < num_stores; i++)
    {
        dp[i] = new double*[1<<num_items];
        for (int j = 0; j < (1 << num_items); j++)
        {
            dp[i][j] = new double[2];
            dp[i][j][0] = -1;
            dp[i][j][1] = -1;
        }
    }

    dp_distance = new double**[num_stores];
    for (int i = 0; i < num_stores; i++)
    {
        dp_distance[i] = new double*[num_stores];
        for (int j = 0; j < num_stores; j++)
        {
            dp_distance[i][j] = new double[2];
            dp_distance[i][j][0] = -1;
            dp_distance[i][j][1] = -1;
        }
    }

    return min(&stores[0], (1 << num_items) - 1 , false, 0);
}

double min(store* s, unsigned int list, bool romlando, unsigned int beento)
{
    if (dp[s->id][list][romlando] != -1)
        return dp[s->id][list][romlando];

    double opt = INF;
    double tmp = INF;

    if (s->id == 0)
    {
        for (int i = 1; i < num_stores; i++)
        {
            tmp = min(&stores[i], list, false, 0) + distance(s, &stores[i], false);
            if (tmp < opt)
                opt = tmp;
        }
    } else
    {
        bool cont = true;
        for (int i = 0; i < num_items && cont; i++)
            if (list >> i & 1 && s->items[i] != -1) //mĂŠg nincs mĂśgvĂŠve ĂŠs kaphatĂł
                for (int j = 1; j < num_stores && cont; j++)
                {

                    store* next = &stores[j];
                    unsigned int nextlist = list - (1 << i);

                    int price = s->items[i];

                    if (nextlist == 0) //jujj
                    {
                        tmp = distance(s, &stores[0], false) + price;
                        cont = false;
                    } else if (== next)
                        tmp = min(&stores[j], nextlist, romlando | items_romlando[i], beento) + price;
                    else if (!(beento >> j & 1))
                        tmp = min(next, nextlist, false, beento | (1 << j)) + distance(s, next, romlando | items_romlando[i]) + price;
                    else
                        continue;

                    if (tmp < opt)
                        opt = tmp;
                }
    }

    dp[s->id][list][romlando] = opt;
    return opt;
}

inline double distance(store* s1, store* s2, bool rom)
{
    if (dp_distance[s1->id][s2->id][rom] != -1)
        return dp_distance[s1->id][s2->id][rom];

    double dist;
    if (rom)
        dist = distance(s1, &stores[0], false) + distance(&stores[0], s2, false);
    //dist = sqrt(pow(s1->x, 2) + pow(s1->y, 2)) + sqrt(pow(s2->x, 2) + pow(s2->y, 2));
    else
        dist = sqrt(pow(s1->- s2->x, 2) + pow(s1->- s2->y, 2)) * price_of_gas;

    dp_distance[s1->id][s2->id][rom] = dist;
    return dp_distance[s1->id][s2->id][rom];
}

void beolvas(char* fnin, char* fnout)
{
    int n;
    FILE* reader = fopen(fnin, "r");
    FILE* printer = fopen(fnout, "w");

    fscanf(reader, "%d", &n);
    for (int caseid = 0; caseid < n; caseid++)
    {
        fscanf(reader, "%d %d %d", &num_items, &num_stores, &price_of_gas);
        string* item_names = new string[num_items];
        items_romlando = new bool[num_items];
        fill(items_romlando, items_romlando + num_items, false);


        for (int i = 0; i < num_items; i++)
        {
            char str[100];
            fscanf(reader, "%s", str);
            item_names[i] = str;

            if (item_names[i][item_names[i].length() - 1] == '!')
            {
                items_romlando[i] = true;
                item_names[i].erase(item_names[i].begin() + item_names[i].length() - 1);
            }
        }

        int tmp;
        char c;
        stores = new store[++num_stores];
        stores[0].= stores[0].= 0;

        for (int i = 0; i < num_stores; i++)
        {
            stores[i].id = i;
            stores[i].item_count = 0;
            stores[i].items = new int[num_items];
            fill(stores[i].items, stores[i].items + num_items, -1);

            if (!= 0)
            {
                string str;
                fscanf(reader, "%d %d", &stores[i].x, &stores[i].y);
                fscanf(reader, "%c", &c);

                while (!= '\n' && !feof(reader))
                {
                    if (!= ' ')
                    {
                        if (!= ':')
                            str += c;
                        else
                        {
                            int id = -1;
                            for (int j = 0; j < num_items; j++)
                                if (str.compare(item_names[j]) == 0)
                                    id = j;
                            fscanf(reader, "%d", &tmp);
                            stores[i].items[id] = tmp;
                            stores[i].item_count++;
                        }
                    } else
                        str = "";
                    fscanf(reader, "%c", &c);
                }
            }
        }
        double result = solve();
        printf("Case #%d: %.7f \n", caseid + 1, result);
        fprintf(printer, "Case #%d: %.7f \n", caseid + 1, result);
    }

    fclose(reader);
    fclose(printer);
}
(Vissza)