Run Time: 0.010
Ranking (as of 2016-10-13): 72 out of 415
Language: C++
/*
UVa 718 - Skyscraper Floors
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_718_Skyscraper_Floors.cpp
*/
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
// extended Euclidean Algorithm
long long gcd_ex(long long a, long long b, long long& x, long long& y)
{
if (b == 0) {
x = 1, y = 0;
return a;
}
long long x1, y1;
long long d = gcd_ex(b, a % b, x1, y1);
x = y1, y = x1 - (a / b) * y1;
return d;
}
bool linear_diophantine_equation(int a, int b, int c,
long long& d, long long& x0, long long& y0)
{
long long u, v;
d = gcd_ex(a, b, u, v);
if (c % d)
return false;
x0 = u * (c / d), y0 = v * (c / d);
return true;
}
bool reachable(int Xi, int Xj, int Yi, int Yj, int F)
{
long long d, x0, y0;
if (!linear_diophantine_equation(Xi, -Xj, Yj - Yi, d, x0, y0))
return false;
int xi = static_cast<int>(Xi / d), xj = static_cast<int>(-Xj / d);
double d_min = static_cast<double>(-x0) / xj,
d_max = (static_cast<double>(F - 1 - Yi) / Xi - x0) / xj;
if (xj < 0)
swap(d_min, d_max);
int ti_min = static_cast<int>(ceil(d_min)), ti_max = static_cast<int>(floor(d_max));
d_min = (y0 - static_cast<double>(F - 1 - Yj) / Xj) / xi,
d_max = static_cast<double>(y0) / xi;
if (xi < 0)
swap(d_min, d_max);
int tj_min = static_cast<int>(ceil(d_min)), tj_max = static_cast<int>(floor(d_max));
return (ti_min > tj_max || ti_max < tj_min) ? false : true;
}
const int E_max = 100;
int Xs[E_max], Ys[E_max];
bool A_reachables[E_max], B_reachables[E_max], reachables[E_max][E_max];
int main()
{
int N;
scanf("%d", &N);
while (N--) {
int F, E, A, B;
scanf("%d %d %d %d", &F, &E, &A, &B);
for (int i = 0; i < E; i++)
scanf("%d %d", &Xs[i], &Ys[i]);
for (int i = 0; i < E; i++) {
A_reachables[i] = A >= Ys[i] && !((A - Ys[i]) % Xs[i]);
B_reachables[i] = B >= Ys[i] && !((B - Ys[i]) % Xs[i]);
}
for (int i = 0; i < E - 1; i++)
for (int j = i + 1; j < E; j++)
reachables[i][j] = reachables[j][i] = reachable(Xs[i], Xs[j], Ys[i], Ys[j], F);
#ifdef DEBUG
for (int i = 0; i < E - 1; i++)
for (int j = i + 1; j < E; j++)
if (reachables[i][j])
printf("[%d][%d] ", i, j);
putchar('\n');
#endif
for (int k = 0; k < E; k++)
for (int i = 0; i < E; i++)
for (int j = 0; j < E; j++)
reachables[i][j] |= reachables[i][k] && reachables[k][j];
bool possible = false;
for (int i = 0; i < E && !possible; i++)
if (A_reachables[i])
for (int j = 0; j < E && !possible; j++)
if (B_reachables[j] && reachables[i][j])
possible = true;
puts((possible) ? "It is possible to move the furniture." :
"The furniture cannot be moved.");
}
return 0;
}
hello can you please make a tutorial about how you solve it ?
ReplyDeleteI read the post by fran.aubry in the below TopCoder forum and applied it:
ReplyDeletehttps://apps.topcoder.com/forums/;jsessionid=A00CC8379806FB86CF9A9CBC5D418C50?module=Thread&threadID=716583&start=0&mc=3#1411778