Cod sursă (job #588994)

Utilizator avatar Vlad_Anica Anica-Popa Vlad-Ioan Vlad_Anica IP ascuns
Problemă Hex Compilator cpp-32 | 2,68 kb
Rundă Arhiva de probleme Status evaluat
Dată 29 mar. 2021 23:46:21 Scor 100
#include <iostream>
#include <stdio.h>
#include <ctype.h>

using namespace std;
const int NMAX = 500, NRDIR = 6, R = 1, B = 2, E = 1, W = (1 << 1), S = (1 << 2), N = (1 << 3);

struct comp
{
    int boss;
    char sides;
    char colour;
}elem[NMAX * NMAX];
FILE *fin;
int dirl[NRDIR] = {-1, -1, 0, 0, 1, 1};
int dirc[NRDIR] = {0, 1, -1, 1, -1, 0};
char colours[2] = {R, B};

inline void UF_init(int n);
int UF_find(int e);
inline bool UF_union(int e1, int e2);
inline int getIndex(int l, int c, int n);
inline int getInt();
inline bool putPiece(int l, int c, char colour, int n);

int main()
{
    int n, cnt, l, c, colour;
    bool over = false, turn = 0;

    fin = fopen("hex.in", "r");
    n = getInt();
    UF_init(n);

    cnt = 0;
    while (!over)
    {
        l = getInt();
        c = getInt();
        over = putPiece(l - 1, c - 1, colours[turn], n);
        cnt++;
        turn = !turn;
    }
    fclose(fin);

    FILE *fout = fopen("hex.out", "w");
    fprintf(fout, "%d", cnt);
    fclose(fout);

    return 0;
}

inline int getIndex(int l, int c, int n) {return n * l + c;}
inline int getInt()
{
    int res = 0;
    char ch;
    while (!isdigit(ch = fgetc(fin)));
    do
        res = res * 10 + ch - '0';
    while (isdigit(ch = fgetc(fin)));
    return res;
}
inline void UF_init(int n)
{
    for (int i = 0; i < n; i++)
    {
        elem[getIndex(0, i, n)].sides |= N;
        elem[getIndex(n - 1, i, n)].sides |= S;
        elem[getIndex(i, 0, n)].sides |= E;
        elem[getIndex(i, n - 1, n)].sides |= W;
    }
    int sq = n * n;
    for (int i = 0; i < sq; i++)
        elem[i].boss = i;
}
int UF_find(int e)
{
    if (elem[e].boss == e)
        return e;
    return elem[e].boss = UF_find(elem[e].boss);
}
inline bool UF_union(int e1, int e2)
{
    int boss1 = UF_find(e1);
    int boss2 = UF_find(e2);

    elem[boss1].boss = boss2;

    elem[boss1].sides |= elem[boss2].sides;
    elem[boss2].sides |= elem[boss1].sides;

    char mask;
    if (elem[boss1].colour == R)
        mask = (E | W);
    else
        mask = (N | S);
    bool ok = 0;
    if (mask == (mask & elem[boss1].sides))
        ok = 1;
    return ok;
}
inline bool putPiece(int l, int c, char colour, int n)
{
    int d;
    bool ok = 0;
    elem[getIndex(l, c, n)].colour = colour;
    for (d = 0; d < NRDIR; d++)
    {
        if (l + dirl[d] >= 0 && c + dirc[d] >= 0 && l + dirl[d] < n && c + dirc[d] < n)
            if (elem[getIndex(l, c, n)].colour == elem[getIndex(l + dirl[d], c + dirc[d], n)].colour)
                ok |= UF_union(getIndex(l, c, n), getIndex(l + dirl[d], c + dirc[d], n));
    }
    return ok;
}