Cod sursa(job #2771896)

Utilizator Gabryel9898Bizdoc Vasile Gabriel Gabryel9898 Data 29 august 2021 23:36:27
Problema Jocul Flip Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.2 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <thread>
#include <mutex>

class Board {
private:
    std::vector<std::vector<int>> internal_board;
public:
    explicit Board(std::vector<std::vector<int>> matrix) {
        internal_board = std::move(matrix);
    }

    Board(const Board &board1) {
        internal_board = board1.internal_board;
    }

    void flip_line(int number) {
        for (auto &col: internal_board[number]) {
            col *= -1;
        }
    }

    void flip_column(int number) {
        for (auto &row: internal_board) {
            row[number] *= -1;
        }
    }

    void print_matrix() {
        std::cout << "\n<------------------->\n";

        for (const auto &row: internal_board) {
            for (const auto &col: row) {
                std::cout << col << " ";
            }
            std::cout << '\n';
        }
    }

    int get_sum() {
        int sum = 0;

        for (const auto &row: internal_board) {
            for (const auto &col: row) {
                sum += col;
            }
        }

        return sum;
    }

    int sum_line(int number) {
        int sum = 0;

        for (const auto &col: internal_board[number]) {
            sum += col;
        }

        return sum;
    }

    int sum_col(int number) {
        int sum = 0;

        for (const auto &row: internal_board) {
            sum += row[number];
        }

        return sum;
    }

    void print_sum() {
        std::cout << '\n' << get_sum() << '\n';
    }
};

std::mutex m;
std::vector<int> sums;

void do_flip(int i, Board *game, int N) {
    auto tmp_game = new Board(*game);

    for (int j = 0; 1 << j <= i; ++j) {
        if (i & (1 << j)) {
            tmp_game->flip_line(j);
//                lines_to_undo.push_back(j);
        }
    }

    for (int k = 0; k < N; ++k) {
        if (tmp_game->sum_col(k) < 0) {
            tmp_game->flip_column(k);
//                columns_to_undo.push_back(k);
        }
    }

    int new_sum = tmp_game->get_sum();
    m.lock();
    sums.push_back(new_sum);
    m.unlock();
//    if (new_sum > max_sum) {
//        max_sum = new_sum;
//    }

//        while (!columns_to_undo.empty()) {
//            tmp_game->flip_column(columns_to_undo.back());
//            columns_to_undo.pop_back();
//        }
//
//        while (!lines_to_undo.empty()) {
//            tmp_game->flip_line(lines_to_undo.back());
//            lines_to_undo.pop_back();
//        }
}

void do_nothing(){

}

int flip_algo() {
    std::string input_file_name("../flip.in");
    std::string output_file_name("../flip.out");

    std::ifstream input_file;
    input_file.open(input_file_name);

    if (!input_file.is_open()) {
        std::cerr << "Could not open the file: '" << input_file_name << "'" << std::endl;
        return EXIT_FAILURE;
    }

    std::ofstream out;
    out.open(output_file_name);

    if (!out.is_open()) {
        std::cerr << "Could not open the file: '" << output_file_name << "'" << std::endl;
        return EXIT_FAILURE;
    }

    int M, N;
    input_file >> M >> N;

    auto matrix = std::vector<std::vector<int>>(M);

    for (auto &row: matrix) {
        row = std::vector<int>(N);

        for (auto &col: row) {
            input_file >> col;
        }
    }

    input_file.close();

    auto game = new Board(matrix);

    int limit = 1 << M;


//    std::vector<int> columns_to_undo;
//    std::vector<int> lines_to_undo;
//    auto tmp_game = game;

    std::vector<std::thread> ths;
    for (int i = 0; i < limit; ++i) {
//        do_flip(i, new Board(*game), N);
        std::thread t1 (do_flip, i, new Board(*game), N);
        ths.push_back(std::move(t1));
    }

    std::cout << ths.size() << std::endl;
    for(auto &t: ths){
        t.join();
    }

    int max_sum = 0;
    for (auto s: sums) {
        if (max_sum < s) {
            max_sum = s;
        }
    }
    out << max_sum;

    out.close();
    return 0;
}

int main() {
    using namespace std;
    using namespace std::chrono;

    auto start = high_resolution_clock::now();
    flip_algo();
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(stop - start);
    cout << duration.count() << endl;
}