2017中国大学生程序设计竞赛-哈尔滨站 Solution
A - Palindrome
题意:给出一个字符串,找出其中有多少个子串满足one-half-palindromic 的定义
思路:其实就是找一个i, j 使得 以i为中轴的回文串长度和以j为中轴的回文串长度都大于j - i + 1
先Manacher 预处理出以每个字符为中轴的最长回文串长度,然后用树状数组维护j ,枚举i
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 const int maxn = 5e5 + 10; 7 8 int l; 9 char Ma[maxn << 1]; 10 int Mp[maxn << 1]; 11 12 inline void Manacher(char s[], int len) 13 { 14 l = 0; 15 Ma[l++] = '$'; 16 Ma[l++] = '#'; 17 for(int i = 0; i < len; ++i) 18 { 19 Ma[l++] = s[i]; 20 Ma[l++] = '#'; 21 } 22 Ma[l] = 0; 23 int mx = 0, id = 0; 24 for(int i = 0; i < l; ++i) 25 { 26 Mp[i] = mx > i ? min(Mp[2 * id - i], mx - i) : 1; 27 while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++; 28 if(i + Mp[i] > mx) 29 { 30 mx = i + Mp[i]; 31 id = i; 32 } 33 } 34 } 35 36 int cnt[maxn << 1]; 37 char str[maxn]; 38 int a[maxn]; 39 int len; 40 41 vector <int> vv[maxn]; 42 43 inline int lowbit(int x) 44 { 45 return x & (-x); 46 } 47 48 inline void update(int x, int val) 49 { 50 for (int i = x; i <= len; i += lowbit(i)) 51 a[i] += val; 52 } 53 54 inline int query(int x) 55 { 56 int res = 0; 57 for (int i = x; i > 0; i -= lowbit(i)) 58 res += a[i]; 59 return res; 60 } 61 62 int main() 63 { 64 int t; 65 scanf("%d", &t); 66 while(t--) 67 { 68 memset(a, 0, sizeof a); 69 scanf("%s", str); 70 len = strlen(str); 71 Manacher(str, len); 72 ll ans = 0; 73 int pos = 1; 74 for(int i = 2 ; i < l; i += 2) 75 { 76 cnt[pos]= Mp[i] / 2 - 1; 77 vv[pos - cnt[pos]].push_back(pos); 78 pos++; 79 } 80 for(int i = 1; i <= pos; ++i) 81 { 82 for (auto it : vv[i]) 83 { 84 update(it, 1); 85 } 86 vv[i].clear(); 87 ans += query(i + cnt[i]) - query(i); 88 // cout << ans << endl; 89 } 90 printf("%lld\n",ans); 91 } 92 return 0; 93 }
B - K-th Number
题意:给出n个数,把这n个数中长度>= k 的区间中的第k小的数放到数组b中,最后求出数组b中的第m大的数
思路:二分答案,然后双指针法判断是否正确,因为存在这样一个性质,假如一个长度>=k的区间里面的第k小的数 >= ans
那么 之后如果加入的数大于它,那么没有影响,如果小于它,要被计数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 const int maxn = 1e5 + 10; 7 8 int n, k ; 9 ll m; 10 int arr[maxn]; 11 int brr[maxn]; 12 13 inline bool check(int mid) 14 { 15 ll tot = 0; 16 ll res = 0; 17 for(int i = 1, j = 0; i <= n; ++i) 18 { 19 while(j <= n && res < k) 20 { 21 if(arr[++j] >= mid) ++res; 22 } 23 if(res >= k) tot += n - j + 1; 24 if(arr[i] >= mid) res--; 25 } 26 return tot >= m; 27 } 28 29 int main() 30 { 31 int t; 32 scanf("%d", &t); 33 while(t--) 34 { 35 scanf("%d %d %lld", &n, &k, &m); 36 for(int i = 1; i <= n; ++i) 37 { 38 scanf("%d", arr + i); 39 brr[i] = arr[i]; 40 } 41 sort(brr + 1, brr + 1 + n); 42 int l = 1; 43 int r = n; 44 int ans = 0; 45 while(r - l >= 0) 46 { 47 int mid = (l + r) >> 1; 48 if(check(brr[mid])) 49 { 50 ans = mid; 51 l = mid + 1; 52 } 53 else 54 { 55 r = mid - 1; 56 } 57 } 58 printf("%d\n",brr[ans]); 59 } 60 return 0; 61 }
C - Confliction
留坑。
D - X-Men
题意:有若干个X-Man 他们要汇合,直到所有Xman的距离都小于等于1的时候,他们就停止行动,一个小时行进一个单位长度,求他们期望的行进时间
思路:因为给的是一棵树,实际上就是最远的两个X-man 的距离 / 2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 6 struct Edge 7 { 8 int to, nx; 9 inline Edge() {} 10 inline Edge(int to, int nx) : to(to), nx(nx) {} 11 }edge[N << 1]; 12 13 int t, n, m; 14 int head[N], pos; 15 bool vis[N]; 16 17 inline void Init() 18 { 19 memset(vis, false, sizeof vis); 20 memset(head, -1, sizeof head); 21 pos = 0; 22 } 23 24 inline void addedge(int u, int v) 25 { 26 edge[++pos] = Edge(v, head[u]); head[u] = pos; 27 edge[++pos] = Edge(u, head[v]); head[v] = pos; 28 } 29 30 int rmq[N << 1]; 31 int F[N << 1]; 32 int P[N], deep[N]; 33 int cnt; 34 35 struct ST 36 { 37 int mm[N << 1]; 38 int dp[N << 1][20]; 39 inline void init(int n) 40 { 41 mm[0] = -1; 42 for (int i = 1; i <= n; ++i) 43 { 44 mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1]; 45 dp[i][0] = i; 46 } 47 for (int j = 1; j <= mm[n]; ++j) 48 for (int i = 1; i + (1 << j) - 1 <= n; ++i) 49 dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1]; 50 } 51 inline int query(int a, int b) 52 { 53 if (a > b) swap(a, b); 54 int k = mm[b - a + 1]; 55 return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b - (1 << k) + 1][k]; 56 } 57 }st; 58 59 inline void DFS(int u, int pre) 60 { 61 F[++cnt] = u; 62 rmq[cnt] = deep[u]; 63 P[u] = cnt; 64 for (int it = head[u]; ~it; it = edge[it].nx) 65 { 66 int v = edge[it].to; 67 if (v == pre) continue; 68 deep[v] = deep[u] + 1; 69 DFS(v, u); 70 F[++cnt] = u; 71 rmq[cnt] = deep[u]; 72 } 73 } 74 75 inline void LCA_Init(int root, int node_num) 76 { 77 cnt = 0; deep[1] = 0; 78 DFS(root, root); 79 st.init(2 * node_num - 1); 80 81 } 82 83 inline int query_lca(int u, int v) 84 { 85 return F[st.query(P[u], P[v])]; 86 } 87 88 inline void Run() 89 { 90 scanf("%d", &t); 91 while (t--) 92 { 93 scanf("%d%d", &n, &m); Init(); 94 for (int i = 1, x; i <= m; ++i) 95 { 96 scanf("%d", &x); 97 vis[x] = true; 98 } 99 for (int i = 1, u, v; i < n; ++i) 100 { 101 scanf("%d%d", &u, &v); 102 addedge(u, v); 103 } 104 LCA_Init(1, n); 105 int ans = 0; 106 for (int i = 1; i <= n; ++i) 107 { 108 if (!vis[i]) continue; 109 for (int j = 1; j <= n; ++j) 110 { 111 if (!vis[j] || j == i) continue; 112 int lca = query_lca(i, j); 113 //printf("%d %d %d\n", i, j, lca); 114 ans = max(ans, deep[i] + deep[j] - 2 * deep[lca]); 115 } 116 } 117 printf("%d.00\n", ans / 2); 118 } 119 } 120 121 int main() 122 { 123 #ifdef LOCAL 124 freopen("Test.in", "r", stdin); 125 #endif 126 127 Run(); 128 129 return 0; 130 }
E - Square Network
留坑。
F - Permutation
题意:给出一个n,里面有1-n,构造一个数列使得满足题目要求
思路:142536 类似这样构造
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define N 100010 6 7 int t, n; 8 int arr[N]; 9 10 int main() 11 { 12 scanf("%d", &t); 13 while (t--) 14 { 15 scanf("%d", &n); 16 int cnt = 1; 17 for (int i = 1; i <= n; i += 2) 18 arr[i] = cnt++; 19 for (int i = 2; i <= n; i += 2) 20 arr[i] = cnt++; 21 for (int i = 1; i <= n; ++i) printf("%d%c", arr[i], " \n"[i == n]); 22 } 23 return 0; 24 }
G - Debug
留坑。
H - A Simple Stone Game
题意:有n堆石子,每次可以移动一个石子要另一堆,如果某一次移动之后,每一堆的石子个数都是x(x > 1) 的倍数,那么游戏结束,问最少需要移动多少个石子使得游戏结束
思路:x一定是石子和的因数,我们可以枚举石子和的每个因数,求出每个因数下的移动次数,取min。至于如何求移动次数,我们可以将每个石子的余数记录下来,并将余数相加再除以因数,可以的到有多少堆石子得到石子,然后再将需要减少的石子数相加就可以得到。注意当只有一个石子的时候为0;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 const ll INFLL = 0x3f3f3f3f3f3f3f3f; 7 const int maxn = 1e5 + 10; 8 9 int n; 10 ll arr[maxn]; 11 ll sum; 12 ll ans; 13 int cnt; 14 ll brr[maxn]; 15 ll crr[maxn]; 16 17 int tot; 18 ll prime[maxn]; 19 bool isprime[maxn]; 20 21 inline void Init_prime() 22 { 23 memset(isprime, true, sizeof isprime); 24 isprime[0] = isprime[1] = false; 25 for(int i = 2; i < maxn; ++i) 26 { 27 if(isprime[i] == true) 28 { 29 prime[tot++] = i; 30 for(int j = i << 1; j < maxn; j += i) 31 { 32 isprime[j] = false; 33 } 34 } 35 } 36 } 37 38 inline void cal(ll x) 39 { 40 ll sum_tmp = 0; 41 int pos = 0; 42 for(int i = 1; i <= n; ++i) 43 { 44 if(arr[i] % x) 45 { 46 crr[pos++] = arr[i] % x; 47 sum_tmp += arr[i] % x; 48 } 49 } 50 ll p = sum_tmp / x; 51 sort(crr, crr + pos); 52 ll res = 0; 53 for(int i = 0; i < pos - p; ++i) 54 { 55 res += crr[i]; 56 } 57 ans = min(ans, res); 58 } 59 60 inline void get_x(ll tmp) 61 { 62 ll tmp_ = sqrt(tmp) + 1; 63 for(int i = 0; i < tot && prime[i] <= tmp_; ++i) 64 { 65 if(tmp % prime[i] == 0) 66 { 67 cal(prime[i]); 68 } 69 } 70 } 71 72 int main() 73 { 74 Init_prime(); 75 int t; 76 scanf("%d",&t); 77 while(t--) 78 { 79 scanf("%d", &n); 80 sum = 0; 81 for(int i = 1; i <= n; ++i) 82 { 83 scanf("%lld", arr + i); 84 sum += arr[i]; 85 } 86 ans = INFLL; 87 get_x(sum); 88 cal(sum); 89 printf("%lld\n", ans); 90 91 } 92 return 0; 93 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 using namespace std; 5 6 #define N 100010 7 #define ll long long 8 #define INF 0x3f3f3f3f 9 10 const double eps = 1e-4; 11 12 struct node 13 { 14 int l, r; 15 double Min; 16 inline node() {} 17 inline node(int l, int r, double Min) : l(l), r(r), Min(Min) {} 18 }tree[N << 2]; 19 20 int cnt, root; 21 22 inline void Init() 23 { 24 cnt = 1; root = 1; 25 tree[1] = node(0, 0, INF * 1.0); 26 } 27 28 inline void update(int &id, int l, int r, int ql, int qr, double val) 29 { 30 if (id == 0) 31 { 32 id = ++cnt; 33 tree[id] = node(0, 0, val); 34 } 35 if (l >= ql && r <= qr) 36 { 37 tree[id].Min = min(tree[id].Min, val); 38 return; 39 } 40 int mid = (l + r) >> 1; 41 if (ql <= mid) update(tree[id].l, l, mid, ql, qr, val); 42 if (qr > mid) update(tree[id].r, mid + 1, r, ql, qr, val); 43 } 44 45 double ansMin; 46 47 inline void query(int id, int l, int r, int pos) 48 { 49 if (id == 0) return; 50 ansMin = min(ansMin, tree[id].Min); 51 if (l == r) 52 return; 53 int mid = (l + r) >> 1; 54 if (pos <= mid) query(tree[id].l, l, mid, pos); 55 else query(tree[id].r, mid + 1, r, pos); 56 } 57 58 struct Interval 59 { 60 int l, r; double a, b; 61 inline void scan() 62 { 63 scanf("%d%d%lf%lf", &l, &r, &a, &b); 64 } 65 inline bool operator < (const Interval &r) const 66 { 67 return l < r.l; 68 } 69 }interval[N]; 70 71 int T; 72 int n, t; 73 74 inline bool check(double x) 75 { 76 double sum = 0.0; 77 for (int i = 1; i <= n; ++i) 78 if (interval[i].a - interval[i].b * x < 0) 79 sum += interval[i].a - interval[i].b * x; 80 Init(); 81 update(root, 0, t, 0, 0, 0.0); 82 for (int i = 1; i <= n; ++i) 83 { 84 ansMin = INF * 1.0; query(root, 0, t, interval[i].l - 1); 85 ansMin = max(ansMin, ansMin + interval[i].a - interval[i].b * x); 86 update(root, 0, t, interval[i].l, interval[i].r, ansMin); 87 } 88 ansMin = INF * 1.0; query(root, 0, t, t); 89 return sum + ansMin > 0; 90 } 91 92 inline void Run() 93 { 94 scanf("%d", &T); 95 while (T--) 96 { 97 scanf("%d%d", &n, &t); 98 for (int i = 1; i <= n; ++i) 99 interval[i].scan(); 100 sort(interval + 1, interval + 1 + n); 101 double l = 0, r = 1000 * 1.0; 102 while (r - l > eps) 103 { 104 double mid = (l + r) / 2; 105 if (check(mid)) 106 l = mid; 107 else 108 r = mid; 109 } 110 printf("%.3f\n", l); 111 } 112 } 113 114 int main() 115 { 116 #ifdef LOCAL 117 freopen("Test.in", "r", stdin); 118 #endif 119 120 Run(); 121 122 return 0; 123 }
树状数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 using namespace std; 5 6 #define N 100010 7 #define ll long long 8 #define INF 0x3f3f3f3f 9 10 const double eps = 1e-4; 11 12 double a[N]; 13 int T, n, t; 14 15 inline int lowbit(int x) 16 { 17 return x & (-x); 18 } 19 20 inline void update(int x, double val) 21 { 22 for (int i = x; i > 0; i -= lowbit(i)) 23 a[i] = min(a[i], val); 24 } 25 26 inline double query(int x) 27 { 28 if (x == 0) return 0; 29 double res = INF; 30 for (int i = x; i <= t; i += lowbit(i)) 31 res = min(a[i], res); 32 return res; 33 } 34 35 struct Interval 36 { 37 int l, r; double a, b; 38 inline void scan() 39 { 40 scanf("%d%d%lf%lf", &l, &r, &a, &b); 41 } 42 inline bool operator < (const Interval &r) const 43 { 44 return l < r.l; 45 } 46 }interval[N]; 47 48 inline bool check(double mid) 49 { 50 double sum = 0.0; 51 for (int i = 1; i <= n; ++i) 52 if (interval[i].a - interval[i].b * mid < 0) 53 sum += interval[i].a - interval[i].b * mid; 54 for (int i = 0; i <= t; ++i) a[i] = INF; 55 for (int i = 1; i <= n; ++i) 56 { 57 double x = query(interval[i].l - 1); 58 x = max(x, interval[i].a - interval[i].b * mid); 59 update(interval[i].r, x); 60 } 61 return sum + query(t) > 0; 62 } 63 64 inline void Run() 65 { 66 scanf("%d", &T); 67 while (T--) 68 { 69 scanf("%d%d", &n, &t); 70 for (int i = 1; i <= n; ++i) 71 interval[i].scan(); 72 sort(interval + 1, interval + 1 + n); 73 double l = 0, r = 1000 * 1.0; 74 while (r - l > eps) 75 { 76 double mid = (l + r) / 2; 77 if (check(mid)) 78 l = mid; 79 else 80 r = mid; 81 } 82 printf("%.3f\n", l); 83 } 84 } 85 86 int main() 87 { 88 #ifdef LOCAL 89 freopen("Test.in", "r", stdin); 90 #endif 91 92 Run(); 93 94 return 0; 95 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 6 struct Edge 7 { 8 int to, nx; 9 inline Edge() {} 10 inline Edge(int to, int nx) : to(to), nx(nx) {} 11 }edge[N << 1]; 12 13 int n; 14 int head[N], pos; 15 int son[N]; 16 int A[N], B[N], C[N]; 17 18 inline void Init() 19 { 20 memset(head, -1, sizeof head); 21 memset(son, 0, sizeof son); 22 memset(A, 0, sizeof A); 23 memset(B, 0, sizeof B); 24 pos = 0; 25 } 26 27 inline void addedge(int u, int v) 28 { 29 edge[++pos] = Edge(v, head[u]); head[u] = pos; 30 edge[++pos] = Edge(u, head[v]); head[v] = pos; 31 } 32 33 inline void DFS_PRE(int u, int pre) 34 { 35 son[u] = 1; int cnt = 0; 36 for (int it = head[u]; ~it; it = edge[it].nx) 37 { 38 int v = edge[it].to; 39 if (v == pre) continue; 40 DFS_PRE(v, u); 41 cnt += A[v]; 42 son[u] += son[v]; 43 } 44 A[u] = max(A[u], cnt); 45 } 46 47 inline void DFS_CHECK(int u, int pre) 48 { 49 int cnt = 1; 50 for (int it = head[u]; ~it; it = edge[it].nx) 51 { 52 int v = edge[it].to; 53 if (v == pre) continue; 54 DFS_CHECK(v, u); 55 cnt += C[v]; 56 } 57 C[u] = min(C[u], cnt); 58 } 59 60 inline bool check(int mid) 61 { 62 for (int i = 1; i <= n; ++i) 63 { 64 C[i] = mid - B[i]; 65 if (A[i] > son[i] || B[i] > (n - son[i]) || A[i] > C[i]) return false; 66 } 67 //for (int i = 1; i <= n; ++i) printf("%d %d\n", i, C[i]); 68 DFS_CHECK(1, 1); 69 //printf("bug -> %d\n", mid); 70 //for (int i = 1; i <= n; ++i) printf("%d %d\n", i, C[i]); 71 for (int i = 1; i <= n; ++i) 72 { 73 if (A[i] > C[i]) return false; 74 } 75 return C[1] >= mid; 76 } 77 78 inline void Run() 79 { 80 int t; scanf("%d", &t); 81 while (t--) 82 { 83 scanf("%d", &n); Init(); 84 for (int i = 1, u, v; i < n; ++i) 85 { 86 scanf("%d%d", &u, &v); 87 addedge(u, v); 88 } 89 int tot, u, v; 90 scanf("%d", &tot); 91 while (tot--) 92 { 93 scanf("%d%d", &u, &v); 94 A[u] = max(A[u], v); 95 } 96 scanf("%d", &tot); 97 while (tot--) 98 { 99 scanf("%d%d", &u, &v); 100 B[u] = max(B[u], v); 101 } 102 DFS_PRE(1, 1); 103 int l = 0, r = n, ans = -1; 104 while (r - l >= 0) 105 { 106 int mid = (l + r) >> 1; 107 if (check(mid)) 108 { 109 ans = mid; 110 r = mid - 1; 111 } 112 else 113 l = mid + 1; 114 } 115 printf("%d\n", ans); 116 } 117 } 118 119 int main() 120 { 121 #ifdef LOCAL 122 freopen("Test.in", "r", stdin); 123 #endif 124 125 Run(); 126 127 return 0; 128 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const double eps = 1e-3; 5 6 inline int sgn(double x) 7 { 8 if (fabs(x) < eps) return 0; 9 if (x < 0) return -1; 10 return 1; 11 } 12 13 struct Point 14 { 15 double x, y; 16 inline Point() {} 17 inline Point(double x, double y) : x(x), y(y) {} 18 inline void scan() { scanf("%lf%lf", &x, &y); } 19 inline Point operator + (const Point &b) const { return Point(x + b.x, y + b.y); } 20 inline Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); } 21 inline Point operator / (const double &k) const { return Point(x / k, y / k); } 22 inline Point operator * (const double &k) const { return Point(x * k, y * k); } 23 inline double operator ^ (const Point &b) const { return x * b.y - y * b.x; } 24 inline double operator * (const Point &b) const { return x * b.x + y * b.y; } 25 inline double distance(Point b) { return hypot(x - b.x, y - b.y); } 26 inline Point rotleft() { return Point(-y, x); } 27 }; 28 29 struct Line 30 { 31 Point s, e; 32 inline Line() {} 33 inline Line(Point s, Point e) : s(s), e(e) {} 34 inline Point crosspoint(Line v) 35 { 36 double a1 = (v.e - v.s) ^ (s - v.s); 37 double a2 = (v.e - v.s) ^ (e - v.s); 38 return Point((s.x * a2 - e.x * a1) / (a2 - a1), (s.y * a2 - e.y * a1) / (a2 - a1)); 39 } 40 inline int relation(Point p) 41 { 42 int c = sgn((p - s) ^ (e - s)); 43 if (c < 0) return 1; 44 if (c > 0) return 2; 45 return 3; 46 } 47 }; 48 49 struct Circle 50 { 51 Point p; 52 double r; 53 inline Circle() {} 54 inline Circle(Point p, double r) : p(p), r(r) {} 55 inline Circle(Point a, Point b, Point c) 56 { 57 Line u = Line((a + b) / 2, ((a + b) / 2) + ((b - a).rotleft())); 58 Line v = Line((b + c) / 2, ((b + c) / 2) + ((c - b).rotleft())); 59 p = u.crosspoint(v); 60 r = p.distance(a); 61 } 62 }; 63 64 int t, n; 65 vector <Point> v; 66 67 inline void Run() 68 { 69 scanf("%d", &t); 70 while (t--) 71 { 72 scanf("%d", &n); 73 double x, y; v.clear(); 74 for (int i = 1; i <= n; ++i) 75 { 76 scanf("%lf%lf", &x, &y); 77 v.emplace_back(x, y); 78 } 79 if (n == 1) 80 { 81 printf("%.6f %.6f 0\n", v[0].x, v[0].y); 82 continue; 83 } 84 else if (n <= 4) 85 { 86 Point ans = Point((v[0].x + v[1].x) / 2, (v[0].y + v[1].y) / 2); 87 double dis = ans.distance(v[0]); 88 printf("%.6f %.6f %.6f\n", ans.x, ans.y, dis); 89 continue; 90 } 91 else 92 { 93 Circle cir; 94 while (true) 95 { 96 random_shuffle(v.begin(), v.end()); 97 //if (Line(v[0], v[1]).relation(v[2]) == 3) continue; 98 cir = Circle(v[0], v[1], v[2]); 99 int cnt = 3; 100 for (int i = 3, len = v.size(); i < len; ++i) 101 if (fabs(cir.p.distance(v[i]) - cir.r) < eps) ++cnt; 102 if (cnt >= ((n + 1) >> 1)) 103 break; 104 } 105 printf("%.6f %.6f %.6f\n", cir.p.x, cir.p.y, cir.r); 106 } 107 } 108 } 109 110 int main() 111 { 112 #ifdef LOCAL 113 freopen("Test.in", "r", stdin); 114 #endif 115 116 Run(); 117 118 return 0; 119 }