algorithm dermuba triangle - andstudy/forge GitHub Wiki
Public Module ModuleMain
Sub Main()
While True
Console.WriteLine(Run(Console.ReadLine()))
End While
End Sub
Function Run(ByVal input As String) As String
Dim strs() As String = input.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
If strs.Length < 2 Then Return Nothing
Dim number1 As Integer = Integer.Parse(strs(0))
Dim number2 As Integer = Integer.Parse(strs(1))
Return Triangle.GetDistance(number1, number2).ToString()
End Function
End Module
Public Enum Direction
Up
Down
End Enum
Public Class Triangle
Shared Function GetDistance(ByVal number1 As Integer, ByVal number2 As Integer) As Double
Dim bigger As Integer = Math.Max(number1, number2)
Dim smaller As Integer = Math.Min(number1, number2)
Dim horizontalDistance As Double = GetHorizontalDistance(smaller, bigger)
Dim verticalDistance As Double = GetVerticalDistance(smaller, bigger)
Dim distance As Double = Math.Sqrt(Math.Pow(horizontalDistance, 2) + Math.Pow(verticalDistance, 2))
Return Math.Round(distance, 3)
End Function
Private Shared Function GetHorizontalDistance(ByVal number1 As Integer, ByVal number2 As Integer)
Dim columnDiff As Integer = GetColumn(number1) - GetColumn(number2)
Return columnDiff * 0.5
End Function
Private Shared Function GetVerticalDistance(ByVal number1 As Integer, ByVal number2 As Integer)
Dim rowDiff As Integer = Math.Abs(GetRow(number1) - GetRow(number2))
Return GetBottomDistance(number1) + (rowDiff - 1) * GetHeight() + GetTopDistance(number2)
End Function
Shared Function GetRow(ByVal number As Integer) As Integer
Dim row As Integer = 0
Dim rowFirst As Long = 0
While True
row += 1
rowFirst = rowFirst + GetCount(row)
If rowFirst > number Then Exit While
End While
Return row
End Function
Shared Function GetColumn(ByVal number As Integer) As Integer
Dim column As Integer
Dim rowFirst As Long
For row As Integer = 1 To GetRow(number) - 1
rowFirst = rowFirst + GetCount(row)
Next
Dim rowLast As Long = rowFirst + GetCount(GetRow(number)) - 1
Dim rowMiddle As Long = (rowFirst + rowLast) \ 2
column = number - rowMiddle
Return column
End Function
Private Shared Function GetDirection(ByVal number As Integer) As Direction
If GetRow(number) And 1 Then
If GetColumn(number) And 1 Then
Return Direction.Down
Else
Return Direction.Up
End If
Else
If GetColumn(number) And 1 Then
Return Direction.Up
Else
Return Direction.Down
End If
End If
End Function
Private Shared Function GetTopDistance(ByVal number As Integer) As Double
If GetDirection(number) = Direction.Up Then
Return (GetHeight() - GetCenterDistance())
Else
Return GetCenterDistance()
End If
End Function
Private Shared Function GetBottomDistance(ByVal number As Integer) As Double
If GetDirection(number) = Direction.Up Then
Return GetCenterDistance()
Else
Return (GetHeight() - GetCenterDistance())
End If
End Function
Shared Function GetHeight() As Double
Return (Math.Sqrt(3) / 2)
End Function
Shared Function GetCenterDistance() As Double
Return (1 / Math.Sqrt(3) / 2)
End Function
Private Shared Function GetCount(ByVal row As Integer) As Integer
Return ((row - 1) * 2) + 1
End Function
End Class
<TestClass()> _
Public Class TriangleTest
<TestMethod()> _
Public Sub GetRowTest()
Assert.AreEqual(1, Triangle.GetRow(0))
Assert.AreEqual(2, Triangle.GetRow(1))
Assert.AreEqual(2, Triangle.GetRow(2))
Assert.AreEqual(2, Triangle.GetRow(3))
Assert.AreEqual(3, Triangle.GetRow(4))
Assert.AreEqual(3, Triangle.GetRow(8))
Assert.AreEqual(4, Triangle.GetRow(9))
Assert.AreEqual(4, Triangle.GetRow(15))
Assert.AreEqual(5, Triangle.GetRow(16))
End Sub
<TestMethod()> _
Public Sub GetColumnTest()
Assert.AreEqual(0, Triangle.GetColumn(0))
Assert.AreEqual(-1, Triangle.GetColumn(1))
Assert.AreEqual(0, Triangle.GetColumn(2))
Assert.AreEqual(1, Triangle.GetColumn(3))
Assert.AreEqual(-2, Triangle.GetColumn(4))
Assert.AreEqual(-1, Triangle.GetColumn(5))
Assert.AreEqual(0, Triangle.GetColumn(6))
Assert.AreEqual(1, Triangle.GetColumn(7))
Assert.AreEqual(2, Triangle.GetColumn(8))
Assert.AreEqual(-3, Triangle.GetColumn(9))
Assert.AreEqual(2, Triangle.GetColumn(14))
End Sub
<TestMethod()> _
Public Sub GetDistanceTest()
Assert.AreEqual(1.528, Triangle.GetDistance(7, 0))
Assert.AreEqual(1.528, Triangle.GetDistance(2, 8))
Assert.AreEqual(0.577, Triangle.GetDistance(10, 9))
Assert.AreEqual(0.577, Triangle.GetDistance(10, 11))
End Sub
<TestMethod()> _
Public Sub GetDistanceTestMore()
Assert.AreEqual(0.0, Triangle.GetDistance(7, 7))
Assert.AreEqual(1.0, Triangle.GetDistance(10, 12))
Dim distance As Double
distance = Math.Round(2 * (Triangle.GetHeight() - Triangle.GetCenterDistance()), 3)
Assert.AreEqual(distance, Triangle.GetDistance(2, 6))
distance = Math.Round(2 * Triangle.GetCenterDistance(), 3)
Assert.AreEqual(distance, Triangle.GetDistance(0, 2))
End Sub
<TestMethod()> _
Public Sub HugeNumberTest()
Assert.AreEqual(0.577, Triangle.GetDistance(2147483646, 2147483647))
End Sub
<TestMethod()> _
Public Sub InputOutputTest()
Dim input As String
input = "0 7"
Assert.AreEqual("1.528", ModuleMain.Run(input))
input = "2 8"
Assert.AreEqual("1.528", ModuleMain.Run(input))
input = "9 10"
Assert.AreEqual("0.577", ModuleMain.Run(input))
input = "10 11"
Assert.AreEqual("0.577", ModuleMain.Run(input))
End Sub
End Class
- ๊ฐ ์ง๋ค์ ์๋ ๊ฑฐ๋ฆฌ๋ฅผ ์ธก์ ํํ ํผํ๊ณ ๋ผ์ค ์ ์์ ์ํด ๊ตฌํจ.
- ํ์๋ฒ์งธ ์ค์ด๋ ์ง์๋ฒ์งธ ์ค์ด๋์ ๋ฐ๋ผ์ ์๊ฐํด์ค์ผํ ๋ณ์๊ฐ ๋ง์๋ค. ใ ใ
#include <stdio.h>
#include <math.h>
#define square(x) ((x)*(x))
#define MIN(x, x2, y, y2) ((x)>(y)?(y+y2):(x+x2))
#define ABS(x) ((x)>0?(x):-(x))
int GetLine(int n)
{
return (int)floor(sqrt((double)n));
}
double GetResult(int n, int m)
{
double x, y;
int LineN = GetLine(n);
int LineM = GetLine(m);
int PositN = n - square(LineN) - LineN;
int PositM = m - square(LineM) - LineM;
int difX = ABS(PositN - PositM);
int difY = ABS(LineN - LineM);
x = difX / 2.0;
y = (difY / 2) * sqrt(3.0);
if( difY & 1 )
{
if( MIN(LineN,PositN, LineM,PositM) & 1 )
{
y += 2*sqrt(3.0)/3;
}
else
{
y += sqrt(3.0)/3;
}
}
if( difX & 1 )
{
if( MIN(LineN,PositN, LineM,PositM) & 1 )
{
if( difY & 1 ) y -= sqrt(3.0)/6;
else y += sqrt(3.0)/6;
}
else
{
if( difY & 1 ) y += sqrt(3.0)/6;
else y -= sqrt(3.0)/6;
}
}
return sqrt(x*x + y*y);
}
int main()
{
int n, m;
while( scanf("%d %d", &n, &m) == 2 )
{
printf("%.3lf\n", GetResult(n, m));
}
return 0;
}
- ์ ์ผ๊ฐํ ๊ทธ๋ฆฌ๋์์ ๋ ์ง์ ๊ฐ ๊ฑฐ๋ฆฌ ๊ตฌํ๋ ๋ฌธ์ !
- (Row, Col) ๊ทธ๋ฆฌ๋๋ฅผ (x, y) ์ค์ ์ขํ๊ณ๋ก ๋ณํ
- Row ๋ n * n ์ผ๋ก ๊ตฌํ๊ณ
- Col ์ ๊ตฌํ์ง ์์.
- ์ญ์ผ๊ฐํ์ผ๋ก ๋๋ ค์ 1,2 ์ฌ๋ถ๋ฉด ์ฌ์ฉ.
- ๊ฐ (x,y) ์ขํ๊ฐ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค.
- IF ๊ฐ ๊ฑฐ์ฌ๋ฆฌ์ง๋ง.. ํจ์ค..
- ์ด๋ฒ ์ฃผ๋ ์ด๊ฑฐ ํ ๋ฌธ์ ๋ง.. ^^;
// "Dermuba Triangle" Solution By Outbreak
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
//#define _TDD
// 1 + 2 + 3 + 4 + 5... = n(n+1) / 2
// 1 + 2 + 3 + 4 + 5... = (n-1)n / 2
//--------------------------------------
// 1 + 3 + 5 + 7 + 9 ... = n * n
// 1 4 9 12 21 = ๊ฐ ํ์ ์ฒซ ์ซ์
// ์ญ์ผ๊ฐํ์ผ๋ก ๋ค์ง์ด์ ํ์ด
//---------------------------------------------------------------------------
namespace Solver
{
// ์ ์ผ๊ฐํ ํ๋ณ์ ๊ธธ์ด
static const double WIDTH = 1;
// ์ ์ผ๊ฐํ ๋์ด
static const double HEIGHT = sqrt((double)3) / 2;
// ์ ์ผ๊ฐํ ๊ผญ์ง์ ์์ ์ธ์ฌ๊น์ง ๊ธด ๊ธธ์ด
static const double UPPER_HEIGHT= HEIGHT * 2 / 3;
// ์ ์ผ๊ฐํ ๊ผญ์ง์ ์์ ์ธ์ฌ๊น์ง ์งง์ ๊ธธ์ด
static const double LOWER_HEIGHT= HEIGHT * 1 / 3;
// * ์ขํ ๋ณํ๊ธฐ
class Converter
{
public:
Converter(int value)
{
X = GetX(value);
Y = GetY(value);
}
static double GetX(int value)
{
int distance = GetColDistace(value);
return distance * WIDTH / 2;
}
static double GetY(int value)
{
int row = GetRow(value);
int distance = GetColDistace(value);
double y = HEIGHT * row;
if( row & 1 )
{
if( distance & 1 )
{
y += UPPER_HEIGHT;
}
else
{
y += LOWER_HEIGHT;
}
}
else
{
if( distance & 1 )
{
y += LOWER_HEIGHT;
}
else
{
y += UPPER_HEIGHT;
}
}
return y;
}
// Row ๊ตฌํ๊ธฐ - ๋ช ๋ฒ์งธ ์ค์ ์๋?
static int GetRow(int value)
{
if( value <= 0 )
return 0;
return (int)sqrt((double)(value));
}
// ํด๋น Row ์ ์ค๊ฐ ์ผ๊ฐํ Column
static int GetCenterCol(int value)
{
double row = GetRow(value);
double center = (((row+1)*(row+1)-1) + row*row) / 2 ;
return (int)center;
}
// ํด๋น Row ์ ์ค๊ฐ ์ผ๊ฐํ๊ณผ์ Column ์ ์ฐจ์ด
static int GetColDistace(int value)
{
int center = GetCenterCol(value);
int distance = center - value;
return distance;
}
public:
double X, Y;
};
// * ์ง - ์ขํ๊ฐ ๊ฑฐ๋ฆฌ ๊ณ์ฐ๊ธฐ
class House
{
public:
House(double x, double y) : x(x), y(y) {}
double operator- (const House& rhs)
{
double xx = this->x - rhs.x;
double yy = this->y - rhs.y;
return sqrt(xx*xx + yy*yy);
}
private:
double x, y;
};
// * ๋ต ๊ตฌํ๊ธฐ
double Calculate(int n, int m)
{
// 1. > ์ ์ (Row, Col) ๊ทธ๋ฆฌ๋๋ฅผ ์ค์ (X, Y) ์ขํ๊ณ๋ก ๋ณํํ๋ค.
Converter c1(n), c2(m);
// 2. > X, Y ์ขํ๊ณ๋ฅผ ์ฐ๋ ์ง์ ๋ง๋ ๋ค.
House h1(c1.X, c1.Y), h2(c2.X, c2.Y);
// 3. > ๋ ์ง๊ฐ์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ค.
return h1 - h2;
}
}
//---------------------------------------------------------------------------
namespace Runner
{
void Execute(istream& in, ostream& out)
{
int n = 0, m = 0;
while( in >> n >> m )
{
if( in.fail() )
break;
out << setprecision(3) << fixed << Solver::Calculate(n,m) << endl;
}
}
}
//---------------------------------------------------------------------------
#ifdef _TDD
#include "unittest++.h"
using namespace Solver;
TEST(Converter_GetRow)
{
// (Row, Col) ์ ์ ๊ทธ๋ฆฌ๋ ์ขํ๊ณ
CHECK_EQUAL(0, Converter::GetRow(0));
CHECK_EQUAL(1, Converter::GetRow(1));
CHECK_EQUAL(2, Converter::GetRow(4));
CHECK_EQUAL(2, Converter::GetRow(7));
CHECK_EQUAL(2, Converter::GetRow(8));
CHECK_EQUAL(3, Converter::GetRow(9));
CHECK_EQUAL(3, Converter::GetRow(11));
}
TEST(Converter_GetCol)
{
// (Row, Col) ์ ์ ๊ทธ๋ฆฌ๋ ์ขํ๊ณ
CHECK_EQUAL(6, Converter::GetCenterCol(4));
CHECK_EQUAL(2, Converter::GetColDistace(4));
CHECK_EQUAL(-2, Converter::GetColDistace(8));
CHECK_EQUAL(-1, Converter::GetColDistace(3));
}
TEST(Converter_GetX)
{
// (X, Y) ์ค์ ์ขํ๊ณ
CHECK_CLOSE( 0, Converter::GetX(0), 0.001);
CHECK_CLOSE( 0.5, Converter::GetX(1), 0.001);
CHECK_CLOSE( -0.5, Converter::GetX(3), 0.001);
CHECK_CLOSE( 1, Converter::GetX(4), 0.001);
CHECK_CLOSE( -1, Converter::GetX(8), 0.001);
}
TEST(Converter_GetY)
{
// (X, Y) ์ค์ ์ขํ๊ณ
CHECK_CLOSE( HEIGHT * Converter::GetRow(6) + UPPER_HEIGHT, Converter::GetY(6), 0.001 );
CHECK_CLOSE( HEIGHT * Converter::GetRow(0) + UPPER_HEIGHT, Converter::GetY(0), 0.001 );
CHECK_CLOSE( HEIGHT * Converter::GetRow(2) + UPPER_HEIGHT / 2, Converter::GetY(2), 0.001 );
}
TEST(House)
{
House h1(0,0), h2(3,4);
CHECK_EQUAL( 5, h1-h2);
}
TEST(Output1)
{
stringstream input;
stringstream output;
input << "0 7\n";
Runner::Execute(input, output);
CHECK_EQUAL("1.528\n", output.str());
}
TEST(Output)
{
stringstream input;
stringstream output;
input <<
"0 7\n"
"2 8\n"
"9 10\n"
"10 11\n";
Runner::Execute(input, output);
CHECK_EQUAL("1.528\n1.528\n0.577\n0.577\n", output.str());
}
#endif
//---------------------------------------------------------------------------
int main()
{
#ifdef _TDD
UnitTest::RunAllTests();
#else
Runner::Execute(cin, cout);
#endif // _TDD
return 0;
}
-
Wrong Answer ๋์ค๋ค์. ๋ฌธ์ ๊ฐ ๋ ๋งํ ํ ์คํธ ์ผ์ด์ค ์์ผ๋ฉด ์ข ์๋ ค์ฃผ์ธ์. [ParkPD]
-
ios์ค์ ๊ฐ์ ๋ฐ๊ฟ์ ์์๋ถ ์ ๋ฐ๋๋ฅผ ๋์ด๊ฑฐ๋ printf๋ฅผ ์ฌ์ฉํด์ ์ถ๋ ฅํด๋ณด์ธ์. [itmentor]
/* @JUDGE_ID:parkpd 110401 Cpp "test" */ /* @BEGIN_OF_SOURCE_CODE */ #include <iostream> #include <vector> #include <set> #include <deque> #include <list> #include <stack> #include <string> #include <algorithm> #include <map> #include <limits> #include <assert.h> #include <iomanip> #include <complex> #include <math.h> //#define _UNIT_TEST #ifdef _UNIT_TEST #include <Windows.h> #include "../UnitTest++/src/UnitTest++.h" #endif using namespace std; #ifdef max #undef max #endif #ifdef min #undef min #endif // Minimum Spanning Tree -> Prim Algorithm ์ ์๊ฐํ๋ฉฐ ํ์์. namespace ATUtil { bool IsInRange(int value, int from, int to) { return (from <= value) && (value <= to); } int ConvertToIndex(char c) { if ('a' <= c && c <= 'z') { return c - 'a'; } else { return -1; } } char ConvertToChar(int i) { return (char)i + 'a'; } #ifdef _UNIT_TEST class CStopWatch { public: CStopWatch() { m_StartTick = GetTickCount(); // gcc ์์ ์ ๋ ์ ์์ผ๋๊น } ~CStopWatch() { cout << "Time passed : " << GetTickCount() - m_StartTick << " milisec.\n"; } int m_StartTick; }; #endif typedef map<int, int> IntDB; typedef vector<int> Ints; typedef list<int> IntList; }; using namespace ATUtil; #ifdef _UNIT_TEST int main() { UnitTest::RunAllTests(); char temp; cin >> temp; return 0; } #endif // code implement namespace ATCode { /////////////////////////////////////////////////////////////// // CSolver class CSolver { public: void GetXY(int n, int& x, int& y) { if (0 == n) // ์์ { x = 0; y = 0; return; } // ์ต์ ํ 1 ๋ฒ. //int comp = 1; //while (comp * comp <= n) //{ // ++comp; //} //y = comp - 1; y = (int)sqrt((double)n); int width = y * 2 + 1; int midValue = (y * y) + width / 2; x = n - midValue; } double Input(int from, int to) { int x1, y1, x2, y2; GetXY(from, x1, y1); GetXY(to, x2, y2); // x ์ฐจ์ด๋ 0.5 km // ์ผ๊ฐํ ๋์ด๋ 0.866025 km // ์ธ์ฌ(circumcenter) ์ค ๊ธด ๊ฑฐ๋ฆฌ๋ 0.577350, ์งง์ ๊ฑฐ๋ฆฌ๋ 0.288675 // ๊ฐ ๊ผญ์ง์ ๊ณผ ์ธ์ฌ์ ์๋ ์ ์ ๊ทธ์ด, ์์ ์ง๊ฐ ์ผ๊ฐํ 3๊ฐ๊ฐ ๋ง๋ค์ด์ก์ ๋, // c ๋ ๋น๋ฉด, b ๋ ๋ฐ๋ฉด, a ๋ ๋์ด // h ๋ ๊ธธ์ด 1 km ์ ์ ์ผ๊ฐํ์ ๋์ด. const double a = 0.288675; const double b = 0.5; const double c = 0.577350; const double h = a + c; int offsetX = abs(x1 - x2); int offsetY = abs(y1 - y2); int manhattanDist = offsetX + offsetY; double diffX = (double)offsetX * b; double diffY = 0.0; if (0 == manhattanDist % 2) // ๊ฐ์ ๋์ด(๋ฐ๋ฅ์ ๊ฐ๊น์ด ์ ) { diffY = offsetY * h; } else { if (0 == offsetY) { diffY = (c - a); } else { if (0 == y1 % 2) { diffY = (offsetY - 1) * h + (2 * a); } else { diffY = (offsetY - 1) * h + (2 * c); } } } double ret = sqrt(diffX * diffX + diffY * diffY); // ์์์ 4์งธ ์๋ฆฌ์์ ๋ฐ์ฌ๋ฆผํ๊ธฐ. ret = ((int)((ret * 1000.0) + 0.5)) * 0.001; return ret; } vector<int> m_Levels; }; /////////////////////////////////////////////////////////////// // CConsole class CConsole { public: static void ConsoleTest(istream& input, ostream& output); }; void CConsole::ConsoleTest(istream& input, ostream& output) { CSolver s; int from, to; while (input >> from >> to) { output << s.Input(from, to) << '\n'; } }; } using namespace ATCode; #ifndef _UNIT_TEST int main() { CConsole::ConsoleTest(cin, cout); return 0; } #else // tests struct FixtureBase { FixtureBase() { } int x, y; stringstream input; stringstream output; }; TEST_FIXTURE(FixtureBase, GetXY) { CSolver g; int tests[] = { 0, 0, -1, 1, 0, 1, 1, 1, -2, 2 }; for (int i = 0; i < sizeof(tests) / sizeof(int); i += 2) { //cout << i / 2 << '\n'; g.GetXY(i / 2, x, y); CHECK_EQUAL(tests[i], x); CHECK_EQUAL(tests[i + 1], y); } } TEST_FIXTURE(FixtureBase, Input) { CSolver g; double tests[] = { 0, 7, 1.528, 2, 8, 1.528, 9, 10, 0.577, 10, 11, 0.577, 7, 7, 0.0, 10, 12, 1.0, 2147483646, 2147483647, 0.577 }; for (int i = 0; i < sizeof(tests) / sizeof(double); i += 3) { cout << "Test Input : " << i / 3 << '\n'; CHECK_CLOSE(tests[i + 2], g.Input((int)tests[i], (int)tests[i + 1]), 0.001); } } TEST_FIXTURE(FixtureBase, ConsoleTest) { input << "0 7\n" "2 8\n" "9 10\n" "10 11\n" ; CConsole::ConsoleTest(input, output); CHECK_EQUAL( "1.528\n" "1.528\n" "0.577\n" "0.577\n", output.str()); } #endif /* @END_OF_SOURCE_CODE */
- 1์ฐจ ์๋ : ๋ชจ๋ ๋ฐ์ดํฐ ํ์ ์ float๋ก ์ฌ์ฉ --> Wrong Answer
- 2์ฐจ ์๋ : ๋ฐ์ดํฐ ํ์ ์ double๋ก ์ฌ์ฉ --> Wrong Answer
- 3์ฐจ ์๋ : ์ถ๋ ฅ ๋ถ๋ถ์ std::cout์์ printf๋ก ๋ฐ๊ฟ --> Solved
-
cout์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์๋ฅผ floatํ์ผ๋ก ์ฒ๋ฆฌํ๋๋ด ๋๋ค. printf๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ios๊ฐ์ ๋ฐ๊ฟ๋ ๋ ๋ฏ...
-
์ ์๋ถ์ ๊ฐ์ด ์ปค์ง๋ฉด float์ ์์๋ถ์ ํํ๋ฒ์๊ฐ ์์์ง๋๋ค.
#include <vector> #include <cmath> #include <iostream> #include <algorithm> #ifdef _UNIT_TEST #include <unittest++.h> #endif const long double PI = 3.14159265358979323846; const long double BaseX = cos( (1.0 / 3.0) * PI ); const long double BaseY = sin( (1.0 / 3.0) * PI ); struct Point { double x,y; double distance(Point& pt) { return sqrt( (pt.x - x) * (pt.x - x) + (pt.y - y) * (pt.y - y) ); } }; std::vector<unsigned long> calculateBaseColumn(unsigned long limitValue) { std::vector<unsigned long> arr; unsigned long nextBaseY = 0; for(unsigned long i = 1 ; nextBaseY <= limitValue; i++) { arr.push_back(nextBaseY); nextBaseY = arr[ arr.size() - 1 ] + i * 2; } return arr; } Point CalculateTriangleCenter( Point* triangleVertices ) { Point center; center.x = triangleVertices[0].x + triangleVertices[1].x + triangleVertices[2].x; center.y = triangleVertices[0].y + triangleVertices[1].y + triangleVertices[2].y; center.x /= 3; center.y /= 3; return center; } void searchRow(std::vector<unsigned long>& array, unsigned long address, unsigned long & localX, unsigned long & localY ) { unsigned long i = 0; for( ; i < array.size() - 1 ; i++) { if( array[i] <= address && address <= array[i+1] ) { break; } } unsigned long leftIndex = i; unsigned long rightIndex = i + 1; unsigned long leftValue = array[leftIndex]; unsigned long rightValue = array[rightIndex]; if( leftValue <= address && address <= leftValue + leftIndex ) { localX = address - leftValue; localY = leftIndex; } else if( rightValue - rightIndex <= address && address <= rightValue) { localX = -(rightValue - address); localY = rightIndex; } } void convertLocalToGlobal( int x, int y, Point& a, Point& b, Point& c) { if( abs(x+y) % 2 == 0 ) //์ง์ { a.x = x; a.y = y; b.x = x - 1; b.y = y + 1; c.x = x + 1; c.y = y + 1; } else //ํ์ { a.x = x; a.y = y + 1; b.x = x - 1; b.y = y; c.x = x + 1; c.y = y; } } void GetTriangleCoordinate(Point& a, Point& b, Point& c, Point* output) { output[0].x = BaseX * a.x; output[0].y = BaseY * a.y; output[1].x = BaseX * b.x; output[1].y = BaseY * b.y; output[2].x = BaseX * c.x; output[2].y = BaseY * c.y; } double GetDistance(std::vector<unsigned long>& array, unsigned long beginTriangle, unsigned long endTriangle ) { unsigned long beginLocalX, beginLocalY; searchRow(array, beginTriangle, beginLocalX, beginLocalY ); Point beginA, beginB, beginC; convertLocalToGlobal(beginLocalX, beginLocalY, beginA,beginB,beginC); Point beginLastPosition[3]; GetTriangleCoordinate(beginA,beginB,beginC, beginLastPosition); Point beginCenter = CalculateTriangleCenter(beginLastPosition); unsigned long endLocalX, endLocalY; searchRow(array, endTriangle, endLocalX, endLocalY ); Point endA, endB, endC; convertLocalToGlobal(endLocalX, endLocalY, endA,endB,endC); Point endLastPosition[3]; GetTriangleCoordinate(endA,endB,endC, endLastPosition); Point endCenter = CalculateTriangleCenter(endLastPosition); return endCenter.distance(beginCenter); } int main() { #ifdef _UNIT_TEST UnitTest::RunAllTests(); #endif std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); while(true) { char ln[512]; std::cin.getline(ln,512); if( ln[0] == 0 ) break; long beg,end; sscanf(ln, "%ld %ld", &beg, &end); double distance = GetDistance(baseCoordinateArray, beg,end); distance += 0.0005; distance *= 1000; distance = (int)distance; distance /= 1000; printf("%.3lf\n", distance); } return 0; } #ifdef _UNIT_TEST TEST(TriangleG) { Point pt[3] = { 0, 0, -BaseX, -BaseY, BaseX, -BaseY }; Point center = CalculateTriangleCenter(pt); CHECK_CLOSE( 0, center.x, 0.001f ); CHECK_CLOSE( -0.57735f, center.y, 0.0005f ); Point pt2[3] = { 0, -2*BaseY, -BaseX, -BaseY, BaseX, -BaseY }; Point center2 = CalculateTriangleCenter(pt2); CHECK_CLOSE( 0, center2.x, 0.001f ); CHECK_CLOSE( -0.57735f * 2, center2.y, 0.0005f ); double distance = center.distance(center2); CHECK_CLOSE( 0.577f, distance, 0.0005f ); } TEST(calculateBaseColumn) { std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); CHECK_EQUAL( baseCoordinateArray[0], 0 ); CHECK_EQUAL( baseCoordinateArray[1], 2 ); CHECK_EQUAL( baseCoordinateArray[2], 6 ); CHECK_EQUAL( baseCoordinateArray[3], 12 ); } TEST(searchRow) { std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); unsigned long localX, localY; searchRow(baseCoordinateArray, 0, localX, localY ); CHECK_EQUAL( 0, localX); CHECK_EQUAL( 0, localY); searchRow(baseCoordinateArray, 8, localX, localY ); CHECK_EQUAL( 2, localX); CHECK_EQUAL( 2, localY); searchRow(baseCoordinateArray, 9, localX, localY ); CHECK_EQUAL( -3, localX); CHECK_EQUAL( 3, localY); } TEST( convertLocalToGlobal ) { std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); Point a,b,c; //<0> convertLocalToGlobal(0, 0, a,b,c); CHECK_CLOSE( a.x, 0, 0.001f ); CHECK_CLOSE( a.y, 0, 0.001f ); CHECK_CLOSE( b.x, -1, 0.001f ); CHECK_CLOSE( b.y, 1, 0.001f ); CHECK_CLOSE( c.x, 1, 0.001f ); CHECK_CLOSE( c.y, 1, 0.001f ); //<2> convertLocalToGlobal(0, 1, a,b,c); CHECK_CLOSE( a.x, 0, 0.001f ); CHECK_CLOSE( a.y, 2, 0.001f ); CHECK_CLOSE( b.x, -1, 0.001f ); CHECK_CLOSE( b.y, 1, 0.001f ); CHECK_CLOSE( c.x, 1, 0.001f ); CHECK_CLOSE( c.y, 1, 0.001f ); //<3> convertLocalToGlobal(1, 1, a,b,c); CHECK_CLOSE( a.x, 1, 0.001f ); CHECK_CLOSE( a.y, 1, 0.001f ); CHECK_CLOSE( b.x, 0, 0.001f ); CHECK_CLOSE( b.y, 2, 0.001f ); CHECK_CLOSE( c.x, 2, 0.001f ); CHECK_CLOSE( c.y, 2, 0.001f ); //<5> convertLocalToGlobal(-1, 2, a,b,c); CHECK_CLOSE( a.x, -1, 0.001f ); CHECK_CLOSE( a.y, 3, 0.001f ); CHECK_CLOSE( b.x, -2, 0.001f ); CHECK_CLOSE( b.y, 2, 0.001f ); CHECK_CLOSE( c.x, 0, 0.001f ); CHECK_CLOSE( c.y, 2, 0.001f ); } TEST(GetTriangleCoordinate) { std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); Point a,b,c; convertLocalToGlobal(0, 0, a,b,c); Point pt[3]; GetTriangleCoordinate(a,b,c, pt); Point center = CalculateTriangleCenter(pt); CHECK_CLOSE( 0, center.x, 0.001f ); CHECK_CLOSE( 0.57735f, center.y, 0.0005f ); Point pt2[3] = {a,b,c}; convertLocalToGlobal(0, 1, a,b,c); GetTriangleCoordinate(a,b,c, pt2); Point center2 = CalculateTriangleCenter(pt2); CHECK_CLOSE( 0, center2.x, 0.001f ); CHECK_CLOSE( 0.57735f * 2, center2.y, 0.0005f ); double distance = center.distance(center2); CHECK_CLOSE( 0.577f, distance, 0.0005f ); } TEST(GetTriangleDistance) { std::vector< unsigned long > baseCoordinateArray; baseCoordinateArray = calculateBaseColumn(3000000000); double distance = GetDistance(baseCoordinateArray, 0,7); CHECK_CLOSE( 1.528f, distance, 0.0005f ); distance = GetDistance(baseCoordinateArray, 2,8); CHECK_CLOSE( 1.528f, distance, 0.0005f ); distance = GetDistance(baseCoordinateArray, 9,10); CHECK_CLOSE( 0.577f, distance, 0.0005f ); distance = GetDistance(baseCoordinateArray, 10,11); CHECK_CLOSE( 0.577f, distance, 0.0005f ); } #endif
-