记录编号 202534 评测结果 AAAAAAAAAA
题目名称 [SYOI 2015] Asm_Def的模拟赛 最终得分 100
用户昵称 GravatarChenyao2333 是否通过 通过
代码语言 C++ 运行时间 0.655 s
提交时间 2015-11-01 13:59:17 内存使用 4.19 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. const int kN = 1000+10;
  6. struct Point {
  7. int x, y;
  8. Point operator - (const Point & p) const {
  9. return (Point) {x-p.x, y-p.y};
  10. }
  11. bool operator < (const Point & p) const {
  12. if (x != p.x) return x < p.x;
  13. return y < p.y;
  14. }
  15. }ps[kN];
  16.  
  17. int N;
  18. int num[kN][kN];
  19.  
  20. int det(const Point & a, const Point & b) {
  21. return a.x*b.y - a.y*b.x;
  22. }
  23.  
  24. bool isUnder(const Point & p, const Point & a, const Point & b) {
  25. return a.x < p.x && p.x <= b.x && det(p-a, b-a) >= 0;
  26. }
  27.  
  28. int calcUnder(int i, int j) {
  29. int ret = 0;
  30. for (int k = 1; k <= N; k++) {
  31. if (isUnder(ps[k], ps[i], ps[j])) ret++;
  32. }
  33. return ret;
  34. }
  35.  
  36. int main() {
  37. // freopen("in.txt", "r", stdin);
  38. freopen("trib.in", "r", stdin);
  39. freopen("trib.out", "w", stdout);
  40. scanf("%d", &N);
  41. for (int i = 1; i <= N; i++) {
  42. int x, y;
  43. scanf("%d %d", &x, &y);
  44. ps[i] = (Point){x, y};
  45. }
  46. sort(ps+1, ps+1+N);
  47. for (int i = 1; i <= N; i++) {
  48. for (int j = i+1; j <= N; j++) {
  49. num[i][j] = calcUnder(i, j);
  50. }
  51. }
  52. int mx = 0, cnt = 0;
  53. for (int i = 1; i <= N; i++) {
  54. for (int j = i+1; j <= N; j++) {
  55. for (int k = j+1; k <= N; k++) {
  56. int left_p = i, mid_p = j, right_p = k;
  57. int tmp = 0;
  58. // 左边垂直
  59. if (ps[left_p].x == ps[mid_p].x) {
  60. tmp = num[mid_p][right_p] - num[left_p][right_p] + 3;
  61. } else if (ps[mid_p].x == ps[right_p].x) {
  62. tmp = num[left_p][right_p] - num[left_p][mid_p] + 2;
  63. } else if (isUnder(ps[mid_p], ps[left_p], ps[right_p])) {
  64. // 这种mid在left_p, right_p下方,这个时候三个端点都没有被算上
  65. tmp = num[left_p][right_p] - num[left_p][mid_p] - num[mid_p][right_p] + 3;
  66. } else {
  67. // mid_p在left_p, right_p的上方,这个时候有一个端点在方案中
  68. tmp = num[left_p][mid_p] + num[mid_p][right_p] - num[left_p][right_p] + 2;
  69. }
  70.  
  71. // printf("%d %d %d ans = %d\n", i, j, k, tmp);
  72. if (tmp > mx) {
  73. mx = tmp;
  74. cnt = 1;
  75. } else if (tmp == mx) {
  76. cnt++;
  77. }
  78. }
  79. }
  80. }
  81. /*
  82. // 检查是否共线
  83. for (int i = 1; i <= N; i++) {
  84. for (int j = i+1; j <= N; j++) {
  85. for (int k = j+1; k <= N; k++) {
  86. if (det(ps[i]-ps[k], ps[i]-ps[j]) == 0) {
  87. printf("wa\n");
  88. }
  89. }
  90. }
  91. }
  92. */
  93.  
  94. printf("%d\n%d", mx, cnt);
  95. return 0;
  96. }