[关闭]
@WangYixu 2018-06-15T11:39:26.000000Z 字数 819 阅读 744

荒岛野人

OI 题解 数论 数学

算法:数论

转化成

枚举即可。

注意要从最大洞穴编号开始走。就这个我WA了3次。

代码

  1. #include<cstdio>
  2. #include<algorithm>
  3. using std::swap;
  4. using std::max;
  5. typedef long long ll;
  6. const int N = 15 + 5;
  7. ll C[N], P[N], L[N];
  8. ll n, m;
  9. ll gcd(ll a, ll b) {
  10. return !b ? a : gcd(b, a%b);
  11. }
  12. void exgcd(ll a, ll b, ll& x, ll& y) {
  13. if (!b) {
  14. x = 1; y = 0;
  15. } else {
  16. exgcd(b, a%b, y, x);
  17. y -= (a/b)*x;
  18. }
  19. }
  20. inline bool check(ll x) {
  21. ll t, k, d;
  22. for (register int i = 1; i <= n; ++i) {
  23. for (register int j = i + 1; j <= n; ++j) {
  24. ll a = P[i] - P[j], b = x, c = C[j] - C[i];
  25. d = gcd(a, b);
  26. if (c % d) continue;
  27. a /= d, b /= d, c /= d;
  28. exgcd(a, b, t, k);
  29. if (b < 0) b = -b;
  30. t = (t*c%b + b) % b;
  31. if (!t) t += (x/d);
  32. if (t <= L[i] && t <= L[j]) return false;
  33. }
  34. }
  35. return true;
  36. }
  37. int main() {
  38. scanf("%d", &n);
  39. m = n;
  40. for (register int i = 1; i <= n; ++i) {
  41. scanf("%d %d %d", &C[i], &P[i], &L[i]);
  42. m = max(m, C[i]);//至少要满足编号要求
  43. }
  44. for (m; m <= 1000000; ++m) {
  45. // printf("%d\n", m);
  46. if (check(m)) {
  47. printf("%d\n", m);
  48. break;
  49. }
  50. }
  51. return 0;
  52. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注