Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Diagnostics;
- using System.IO;
- class Algorithm
- {
- static int c, n, maxMove;
- static int[,] field;
- static Data maxElement;
- static float bestResult = float.MaxValue;
- static StringBuilder result = new StringBuilder(12000);
- static float acceleratorStep = 0f;
- static float acceleratorStat = 1f;
- static double secondsForLoop = 0;
- // Information about possible moves and their result
- struct Data
- {
- public int row;
- public int col;
- public float coefficient;
- public int move;
- }
- static void Main()
- {
- Stopwatch totalTime = new Stopwatch();
- Stopwatch turnTime = new Stopwatch();
- totalTime.Start();
- InputField();
- //InputFileConsole();
- int startSum = CalculateSum();
- bool firstTurn = true;
- do
- {
- if (firstTurn)
- {
- turnTime.Start();
- CalculateCoefficients();
- }
- else
- {
- CalculateCoefficients();
- }
- if (maxElement.coefficient > 0)
- {
- MakeMoves(maxElement.row, maxElement.col, maxElement.move);
- maxElement.coefficient = 0;
- }
- else
- {
- Console.WriteLine();
- JustTake();
- }
- if (firstTurn)
- {
- turnTime.Stop();
- secondsForLoop = turnTime.Elapsed.TotalMilliseconds * c / 1000;
- CalculateAccelerators();
- }
- firstTurn = false;
- } while ((maxMove > 0) && (totalTime.ElapsedMilliseconds < 2820));
- if (maxMove > 0)
- {
- JustTake();
- }
- Console.WindowHeight = 1;
- Console.WindowWidth = 14;
- Console.WriteLine(result);
- Console.WindowHeight = 30;
- Console.WindowWidth = 40;
- //int endSum = CalculateSum();
- //Console.WriteLine("Result = {0}", startSum - endSum);
- totalTime.Stop();
- //Console.WriteLine("Time = {0}", totalTime.ElapsedMilliseconds);
- //Console.WriteLine("Time = {0}", secondsForLoop);
- //Console.WriteLine("Ostavashti hodove = {0}", maxMove);
- //Console.WriteLine("ACCELERATOR = {0}", acceleratorStat);
- }
- // This method calculates accelerator coefficient.
- // Coefficient depends from first loop to make move.
- // Accelerator
- static void CalculateAccelerators()
- {
- if (secondsForLoop > 195)
- {
- acceleratorStat = 0.138f;
- }
- else if (secondsForLoop > 65)
- {
- acceleratorStat = 0.17f;
- }
- else if (secondsForLoop > 25)
- {
- acceleratorStat = 0.22f;
- }
- else if (secondsForLoop > 12)
- {
- acceleratorStat = 0.55f;
- }
- else if (secondsForLoop > 2.5d)
- {
- acceleratorStat = 0.8f;
- }
- else
- {
- acceleratorStat = 1f;
- }
- }
- // Method that calculate sum of all fields
- static int CalculateSum()
- {
- int sum = 0;
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- sum += field[i, j];
- }
- }
- return sum;
- }
- // This method just takes from matrix
- static void JustTake()
- {
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- while ((field[i, j] > 0) && (maxMove > 0))
- {
- MakeMoves(i, j, -1);
- }
- }
- }
- }
- // Take full input information from console
- // Build matrix field[] with input information
- static void InputField()
- {
- c = int.Parse(Console.ReadLine());
- n = int.Parse(Console.ReadLine());
- maxMove = c;
- field = new int[n, n];
- for (int row = 0; row < n; row++)
- {
- string rowText = Console.ReadLine();
- string[] rowCells = rowText.Split(' ');
- for (int col = 0; col < n; col++)
- {
- field[row, col] = int.Parse(rowCells[col]);
- }
- }
- }
- // After we have calculate moves that can destroy at least 2 towers,
- //we use make moves to do this
- static void MakeMoves(int row, int col, int move)
- {
- if (move > 0)
- {
- for (int i = 0; i < move; i++)
- {
- //result += "put " + row + " " + col + "\n";
- result.Append("put ");
- result.Append(row);
- result.Append(" ");
- result.Append(col);
- result.Append("\n");
- maxMove--;
- CheckNeighbours(row, col, 1);
- }
- }
- else
- {
- for (int i = 0; i < -1 * move; i++)
- {
- result.Append("take ");
- result.Append(row);
- result.Append(" ");
- result.Append(col);
- result.Append("\n");
- maxMove--;
- CheckNeighbours(row, col, -1);
- }
- }
- //PrintField();
- }
- // Make moves and destroy all equal towers
- static void CheckNeighbours(int row, int col, int move)
- {
- field[row, col] += move;
- if (field[row, col] < 0)
- {
- field[row, col] = 0;
- }
- else
- {
- int height = field[row, col];
- if ((row + 1 < n) && (height == field[row + 1, col]))
- {
- field[row + 1, col] = 0;
- field[row, col] = 0;
- }
- if ((col + 1 < n) && (height == field[row, col + 1]))
- {
- field[row, col + 1] = 0;
- field[row, col] = 0;
- }
- if ((row - 1 >= 0) && (height == field[row - 1, col]))
- {
- field[row - 1, col] = 0;
- field[row, col] = 0;
- }
- if ((col - 1 >= 0) && (height == field[row, col - 1]))
- {
- field[row, col - 1] = 0;
- field[row, col] = 0;
- }
- }
- }
- // Calculate best result in one move
- static float OneMoveResult(int[] neighbours, int element, int move)
- {
- int result = element;
- float coefficient = 0f;
- foreach (int neighbour in neighbours)
- {
- if (element + move == neighbour)
- {
- result += neighbour;
- }
- }
- if (move != 0)
- {
- coefficient = (float)result / (float)move;
- }
- if (move < 0)
- {
- coefficient *= -1;
- }
- return coefficient;
- }
- // Method that calculate best coefficients for all elements in field
- static void CalculateCoefficients()
- {
- Data element;
- float maxCoefficient = 0f;
- if (maxMove % 2 == 0)
- {
- for (int row = 0; row < n; row += 1 + (int)acceleratorStep)
- {
- for (int col = 0 + (row % 2); col < n; col += 2 * (int)(1 + acceleratorStep))
- {
- if (field[row, col] > 0)
- {
- element = CalculateCoefficient(row, col);
- if (element.coefficient > maxCoefficient)
- {
- maxCoefficient = element.coefficient;
- maxElement = element;
- if (maxElement.coefficient > bestResult * acceleratorStat)
- {
- return;
- }
- }
- }
- }
- }
- }
- else
- {
- for (int row = n - 1; row >= 0; row -= 1 + (int)acceleratorStep)
- {
- for (int col = n - 1 - (row % 2); col >= 0; col -= 2 * (int)(1 + acceleratorStep))
- {
- if (field[row, col] > 0)
- {
- element = CalculateCoefficient(row, col);
- if (element.coefficient > maxCoefficient)
- {
- maxCoefficient = element.coefficient;
- maxElement = element;
- if (maxElement.coefficient > bestResult * acceleratorStat)
- {
- return;
- }
- }
- }
- }
- }
- }
- bestResult = maxCoefficient;
- }
- // Calculate best coefficient for one field
- private static Data CalculateCoefficient(int row, int col)
- {
- int[] neighbours = new int[4];
- int positiveMove = int.MaxValue;
- int negativeMove = int.MinValue;
- for (int i = 0; i < 4; i++)
- {
- switch (i)
- {
- case 0:
- if (row + 1 < n)
- {
- neighbours[0] = field[row + 1, col];
- }
- break;
- case 1:
- if (col + 1 < n)
- {
- neighbours[1] = field[row, col + 1];
- }
- break;
- case 2:
- if (row - 1 >= 0)
- {
- neighbours[2] = field[row - 1, col];
- }
- break;
- case 3:
- if (col - 1 >= 0)
- {
- neighbours[3] = field[row, col - 1];
- }
- break;
- default:
- break;
- }
- int oneMove = neighbours[i] - field[row, col];
- if ((oneMove > maxMove) || (oneMove < -maxMove))
- {
- oneMove = 0;
- }
- if ((oneMove > 0) && (oneMove < positiveMove))
- {
- positiveMove = oneMove;
- }
- else if ((oneMove < 0) && (oneMove > negativeMove))
- {
- negativeMove = oneMove;
- }
- }
- if (positiveMove == int.MaxValue)
- {
- positiveMove = 0;
- }
- if (negativeMove == int.MinValue)
- {
- negativeMove = 0;
- }
- Data element = new Data();
- element.coefficient = 0f;
- if (positiveMove == 0)
- {
- element.coefficient = OneMoveResult(neighbours, field[row, col], negativeMove);
- element.move = negativeMove;
- }
- else if (negativeMove == 0)
- {
- element.coefficient = OneMoveResult(neighbours, field[row, col], positiveMove);
- element.move = positiveMove;
- }
- else
- {
- element.coefficient = OneMoveResult(neighbours, field[row, col], negativeMove);
- element.move = negativeMove;
- float coefficient = OneMoveResult(neighbours, field[row, col], positiveMove);
- if (coefficient > element.coefficient)
- {
- element.coefficient = coefficient;
- element.move = positiveMove;
- }
- }
- element.row = row;
- element.col = col;
- return element;
- }
- // Next methods are used only for test
- static void PrintField()
- {
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- Console.Write("{0,4} ", field[i, j]);
- }
- Console.WriteLine();
- }
- }
- private static void InputFile()
- {
- StreamReader reader = new StreamReader("../../input.txt");
- using (reader)
- {
- c = int.Parse(reader.ReadLine());
- n = int.Parse(reader.ReadLine());
- maxMove = c;
- field = new int[n, n];
- for (int row = 0; row < n; row++)
- {
- string rowText = reader.ReadLine();
- string[] rowCells = rowText.Split(' ');
- for (int col = 0; col < n; col++)
- {
- field[row, col] = int.Parse(rowCells[col]);
- }
- }
- }
- }
- private static void InputFileConsole()
- {
- StreamReader reader = new StreamReader("../../input.txt");
- Console.SetIn(reader);
- c = int.Parse(Console.ReadLine());
- n = int.Parse(Console.ReadLine());
- maxMove = c;
- field = new int[n, n];
- for (int row = 0; row < n; row++)
- {
- string rowText = Console.ReadLine();
- string[] rowCells = rowText.Split(' ');
- for (int col = 0; col < n; col++)
- {
- field[row, col] = int.Parse(rowCells[col]);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement