Pagini recente »
Istoria paginii runda/2022-02-16-clasa-5-tema-27/clasament
|
Istoria paginii runda/2020-09-18-clasa-6-tema-03/clasament
|
Istoria paginii runda/2014-05-20-clasa-78-tema-28
|
Cod sursă (job #692301)
|
Cod sursă (job #514781)
Cod sursă (job
#514781)
//aproape identica cu solutia oficiala, nu stiam cum sa verific daca a castigat cineva :(
#include <fstream>
#define Nmax 1000
#define NORTH 0x08 //punctele cardinale reprezentate pe un singur octet
#define EAST 0x04
#define SOUTH 0x02
#define WEST 0x01
#define RED 1
#define BLUE 2
using namespace std;
ifstream in ("hex.in");
ofstream out ("hex.out");
int n;
struct hexagon
{
int h;
int p;
char color;
char sides;
};
hexagon v[(Nmax+1)*(Nmax+1)+1];
int index(int i,int j) //liniarizare
{
return i*(n+2)+j;
}
void _init(int n) //creez multimile initiale
{
int i,j;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
{
int ind=index(i,j);
v[ind].p=ind;
v[ind].h=1;
}
for (i=1;i<=n;i++) //laturile matricei si punctele cardinale pe care le ating
{
v[index(i,1)].sides|=WEST;
v[index(1,i)].sides|=NORTH;
v[index(i,n)].sides|=EAST;
v[index(n,i)].sides|=SOUTH;
}
}
int _find(int x) //caut radacina si actualizez radacina tuturor copiilor
{
int r=x;
while (v[r].p!=r)
r=v[r].p;
while (v[x].p!=r)
{
int tmp=v[x].p;
v[x].p=r;
x=tmp;
}
return r;
}
void _union(int x,int y) //reunesc 2 multimi x si y, reprezentand 2 hexagoane
{
if (v[x].color!=v[y].color) //daca sunt de culori diferite, nu ma ating de ele
return;
x=_find(x),y=_find(y);
if (x!=y)
{
if (v[x].h>v[y].h)
v[y].p=x;
else if (v[x].h<v[y].h)
v[x].p=y;
else
v[x].p=y,v[y].h++;
}
v[x].sides|=v[y].sides; //laturile de care se ating sunt puse in legatura una cu alta
v[y].sides|=v[x].sides;
}
bool mutare(int l,int c,int color) //pasii realizati la fiecare mutare
{
int ind=index(l,c);
v[ind].color=color+1;
_union(ind,index(l,c+1)); //unesc, daca au aceeasi culoare, hexagoanele vecine
_union(ind,index(l,c-1));
_union(ind,index(l+1,c-1));
_union(ind,index(l+1,c));
_union(ind,index(l-1,c));
_union(ind,index(l-1,c+1));
int r=_find(ind); //verific daca a castigat cineva
int incercare=(color==RED) ? (EAST | WEST) : (NORTH | SOUTH); //combin est cu vest sau nord cu sud pentru ca si distantele din v[x].sides sunt combinate
return (v[r].sides&incercare)==incercare; //daca s-a creat o legatura intre 2 puncte cardinale opuse, s-a terminat
}
int main()
{
int moves=0,l,c;
in>>n;
_init(n);
while (in>>l>>c)
{
moves++;
if (mutare(l,c, (moves % 2) ? RED : BLUE)) //daca moves e impar, culoarea e rosie, altfel albastra
{
out<<moves;
return 0;
}
}
return 0;
}