#include #include #include #include #include #include #define MAXN 250 #define MAXN2 250*250+1 #define MAXC 501 #define MAX_TIME 1 using namespace std; struct searchResult{ set newBorders; set newNodes; }; int board[MAXN][MAXN], indexedBoard[MAXN][MAXN]; // 0 - x // 0 - y int coordinates[MAXN2][2]; vector colorFrequency(MAXC); int size, colors; int foundColors = 0; int totalMoves = 0; int moves[MAXN2]; int startX, startY; int nextColor; searchResult nextMove; clock_t startTime; set graph[MAXN2]; set usedNodes, borderNodes; void getTime(){ cout << (double)(clock() - startTime) / ((double)CLOCKS_PER_SEC) << endl; } // --- Actions over nodes void addRelation(int node, int value){ if(value < 0) value *= -1; if(value != node) graph[node].insert(value); } bool isNodeUsed(int node){ return usedNodes.count(node); } int getNodeX(int node){ return coordinates[node][0]; } int getNodeY(int node){ return coordinates[node][1]; } bool isNodeInColor(int node, int color){ return ( board [coordinates[node][0]] [coordinates[node][1]] == color ); } bool isNodeInside(int node){ set::iterator it; for (it=graph[node].begin(); it!=graph[node].end(); it++){ if(usedNodes.count(*it)==0) return false; } return true; } int getNodeColor(int node){ return board[getNodeX(node)][getNodeY(node)]; } // --- I/O functions void read(){ FILE *fp; fp = fopen ( "flood-it.in","r") ; fscanf (fp, "%d", &size); fscanf (fp, "%d", &colors); int input; for(int i=0;i::iterator it; cout << "Used: " << endl; for(it=usedNodes.begin(); it!=usedNodes.end(); it++) cout << *it << " "; cout << endl; cout << "Border: " << endl; for(it=borderNodes.begin(); it!=borderNodes.end(); it++) cout << *it << " "; cout << endl; } void info(){ set::iterator it; cout << "Total nodes: " << foundColors << endl; for(int i=1;i<=foundColors;i++){ cout << "Node: " << i << endl; int x = coordinates[i][0]; int y = coordinates[i][1]; cout << "x: " << x << " y: " << y << " color: " << board[x][y] << endl; cout << "neighbours:"; for (it=graph[i].begin(); it!=graph[i].end(); it++) cout << " " << *it; cout << endl; } } // --- Nodes preparation void indexingFlood(int i, int j, int color){ board[i][j] *= -1; indexedBoard[i][j] = foundColors; if(i+1 < size && board[i+1][j] == color) indexingFlood(i+1, j, color); if(j+1 < size && board[i][j+1] == color) indexingFlood(i, j+1, color); if(i-1 >= 0 && board[i-1][j] == color) indexingFlood(i-1, j, color); if(j+1 >= 0 && board[i][j-1] == color) indexingFlood(i, j-1, color); } void neighbouringFlood(int i, int j, int index){ board[i][j] *= -1; indexedBoard[i][j] *= -1; if(i+1 < size){ if(indexedBoard[i+1][j] == index) neighbouringFlood(i+1, j, index); else addRelation(index, indexedBoard[i+1][j]); } if(j+1 < size){ if(indexedBoard[i][j+1] == index) neighbouringFlood(i, j+1, index); else addRelation(index, indexedBoard[i][j+1]); } if(0 <= i-1){ if(indexedBoard[i-1][j] == index) neighbouringFlood(i-1, j, index); else addRelation(index, indexedBoard[i-1][j]); } if(0 <= j-1){ if(indexedBoard[i][j-1] == index) neighbouringFlood(i, j-1, index); else addRelation(index, indexedBoard[i][j-1]); } } void prepare(){ int color; for(int i=0;i 0){ foundColors++; colorFrequency[color]++; coordinates[foundColors][0] = i; coordinates[foundColors][1] = j; coordinates[foundColors][2] = 0; indexingFlood(i,j, color); } } } for(int i=0;i 0) neighbouringFlood(i,j, indexedBoard[i][j]); } } delete [] indexedBoard; } void initStart(int node){ startX = getNodeX(node); startY = getNodeY(node); totalMoves = -1; usedNodes.insert(node); set::iterator it; for (it=graph[node].begin(); it!=graph[node].end(); it++) borderNodes.insert(*it); } int getMoveScore(searchResult move, int color){ int newBorders = move.newBorders.size(); int newNodes = move.newNodes.size(); if (newNodes == 0) return 0; int mark = 0; mark += newBorders; mark += newNodes; if ( colorFrequency[color] == newNodes) mark += 7; return mark; } int decideNextMove(){ map results; set::iterator border, outer; map::iterator it; for (border=borderNodes.begin(); border!=borderNodes.end(); border++){ results[getNodeColor(*border)].newNodes.insert(*border); for (outer=graph[*border].begin(); outer!=graph[*border].end(); outer++){ if(!isNodeUsed(*outer)){ results[getNodeColor(*border)].newBorders.insert(*outer); } } } int maxScore = -1, score; for ( it=results.begin() ; it != results.end(); it++ ){ score = getMoveScore((*it).second, (*it).first); if(score > maxScore){ maxScore = score; nextMove = (*it).second; nextColor = (*it).first; } } return maxScore; } void makeNextMove(){ moves[++totalMoves] = nextColor; colorFrequency[nextColor] -= nextMove.newNodes.size(); set::iterator border; for (border=nextMove.newNodes.begin(); border!=nextMove.newNodes.end(); border++){ usedNodes.insert(*border); borderNodes.erase(*border); } for (border=nextMove.newBorders.begin(); border!=nextMove.newBorders.end(); border++){ borderNodes.insert(*border); } } void chooseStartNode(){ set::iterator border, outer; int bestStart = 1,maxScore=-1,score; vector borderColors; int colorCount[colors+1]; for(int i =0;i