Codeforces Round #339 (Div. 1) ABC
2016-01-16 13:45
225 查看
A Peter and Snow Blower
多边形与中心最远距离作大圆,最近距离作小圆,答案是大圆面积减去小圆面积。检查下中心是否在多边形内,如果在最近距离就是0。注意最远距离只会出现在点上,而最近距离可能出现在点上和边上。这题没什么意思,就是贴下计算几何模板。import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { class Point { double x; double y; Point(double x, double y) { this.x = x; this.y = y; } double Cross(Point point) { return x * point.y - y * point.x; } double Dot(Point point) { return x * point.x + y * point.y; } double Distance(Point point) { return Math.sqrt((x - point.x) * (x - point.x) + (y - point.y) * (y - point.y)); } Point Sub(Point point) { return new Point(x - point.x, y - point.y); } } int n; Point pt; Point[] pts; void Solve() { FastScanner scan = new FastScanner(); n = scan.nextInt(); int px = scan.nextInt(); int py = scan.nextInt(); pt = new Point(px, py); pts = new Point[n + 1]; for (int i = 0; i < n; i++) { int x = scan.nextInt(); int y = scan.nextInt(); pts[i] = new Point(x, y); } pts = pts[0]; boolean positive = false; boolean negative = false; for (int i = 0; i < n; i++) { Point vec = pts[i + 1].Sub(pts[i]); double X = vec.Cross(pt.Sub(pts[i])); if (X < 0) { negative = true; } if (X > 0) { positive = true; } } double maxDist = 0; double minDist = Double.MAX_VALUE; if (!(positive && negative)) { minDist = 0; } for (int i = 0; i < n; i++) { double p2p = pt.Distance(pts[i]); maxDist = Math.max(maxDist, p2p); minDist = Math.min(minDist, p2p); double a = pts[i].Distance(pts[i + 1]); double b = pts[i].Distance(pt); double c = pts[i + 1].Distance(pt); double p = (a + b + c) / 2; double S = Math.sqrt(p * (p - a) * (p - b) * (p - c)); double p2l = S * 2 / a; if (pt.Sub(pts[i]).Dot(pts[i + 1].Sub(pts[i])) * pt.Sub(pts[i + 1]).Dot(pts[i].Sub(pts[i + 1])) >= 0) minDist = Math.min(minDist, p2l); } double ans = Math.PI * (maxDist * maxDist - minDist * minDist); System.out.print(ans); } public static void main(String[] args) { new Main().Solve(); } public static class FastScanner { BufferedReader br; StringTokenizer st; public FastScanner(String s) { try { br = new BufferedReader(new FileReader(s)); } catch (FileNotFoundException e) { e.printStackTrace(); } } public FastScanner() { br = new BufferedReader(new InputStreamReader(System.in)); } String nextToken() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } public boolean EOF() { if (st != null && st.hasMoreTokens()) { return false; } else { String line = null; try { line = br.readLine(); } catch (IOException e) { e.printStackTrace(); } if (line == null) return true; st = new StringTokenizer(line); return false; } } int nextInt() { return Integer.parseInt(nextToken()); } long nextLong() { return Long.parseLong(nextToken()); } double nextDouble() { return Double.parseDouble(nextToken()); } } }
B Skills
首先排序,然后枚举加满的技能的数量。对于每次枚举,用二分计算能把最低级的技能加到多少,取一个总分的最大值即可。写的时候要细心,不然容易出bug。另外,原本以为加满技能的数量->总分是一个凸函数,写了个三分套二分一直WA。后来把三分作了些修改,当区间小到一定程度时改为枚举过掉了(实际上姿势还是不对的)。。因为后来事实证明那不一定是凸函数。写完以后还有个发现,自变量离散(因为只能取整数)和连续的三分是有区别的。
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.Arrays; import java.util.StringTokenizer; public class Main { class Node implements Comparable<Node> { long val; int id; @Override public int compareTo(Node o) { // TODO Auto-generated method stub if (val < o.val) { return -1; } else if (val == o.val) { return 0; } else { return 1; } } } int n; long A, cf, cm; long m; Node[] a; long[] rsum; long[] lsum; long BinerySearch(int l, int r, long val) { int mid; int pos = 0; while (l <= r) { mid = (l + r) >> 1; if (lsum[mid] <= val) { pos = mid; l = mid + 1; } else { r = mid - 1; } } val -= lsum[pos]; long res = a[pos].val + val / (pos + 1); res = Math.min(res, A); return res; } void Solve() { FastScanner scan = new FastScanner(); n = scan.nextInt(); A = scan.nextLong(); cf = scan.nextLong(); cm = scan.nextLong(); m = scan.nextLong(); a = new Node[n + 1]; lsum = new long[n + 1]; rsum = new long[n + 1]; for (int i = 0; i < n; i++) { a[i] = new Node(); a[i].val = scan.nextLong(); a[i].id = i; } Arrays.sort(a, 0, n); for (int i = 1; i < n; i++) { lsum[i] = lsum[i - 1] + (a[i].val - a[i - 1].val) * i; } lsum = Long.MAX_VALUE; int leftMost = 0; for (int i = n - 1; i >= 0; i--) { rsum[i] = rsum[i + 1] + (A - a[i].val); if (rsum[i] > m) { leftMost = i + 1; break; } } long maxP = 0; int left = leftMost; long MIN = A; for (int i = n; i >= leftMost; i--) { long mm = m - rsum[i]; long tmp = BinerySearch(0, i - 1, mm); long power = tmp * cm + (n - i) * cf; if (tmp == A) { power = A * cm + n * cf; } if (power >= maxP) { maxP = power; left = i; MIN = tmp; } } long[] ans = new long[n + 1]; for (int i = 0; i < n; i++) { int id = a[i].id; ans[id] = a[i].val; if (i >= left) { ans[id] = A; } else if (ans[id] < MIN) { ans[id] = MIN; } } PrintWriter out = new PrintWriter(System.out); out.println(maxP); for (int i = 0; i < n; i++) { out.print(ans[i] + " "); } out.println(); out.flush(); } public static void main(String[] args) { new Main().Solve(); } public static class FastScanner { BufferedReader br; StringTokenizer st; public FastScanner(String s) { try { br = new BufferedReader(new FileReader(s)); } catch (FileNotFoundException e) { e.printStackTrace(); } } public FastScanner() { br = new BufferedReader(new InputStreamReader(System.in)); } String nextToken() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } public boolean EOF() { if (st != null && st.hasMoreTokens()) { return false; } else { String line = null; try { line = br.readLine(); } catch (IOException e) { e.printStackTrace(); } if (line == null) return true; st = new StringTokenizer(line); return false; } } int nextInt() { return Integer.parseInt(nextToken()); } long nextLong() { return Long.parseLong(nextToken()); } double nextDouble() { return Double.parseDouble(nextToken()); } } }
C Necklace
这题我写的比较繁琐。首先找规律可以发现如果出现2个及以上奇数,则无法形成回文。否则,答案是这些数的GCD。构造的时候,可以递归去拼接(拆成gcd段,交替连接当前字符和其他字符)。这个过程比较复杂,详见代码。import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.StringTokenizer; public class Main { int n; int[] a; char[] chars; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } StringBuilder Construct(int[] arr, int s) { if (s > n) { return new StringBuilder(""); } StringBuilder res = new StringBuilder(); int odd = 0; for (int i = s; i <= n; i++) { if (arr[i] % 2 == 1) { odd++; // swap int tmp = arr[i]; arr[i] = arr[s]; arr[s] = tmp; char tmp2 = chars[i]; chars[i] = chars[s]; chars[s] = tmp2; } } if (odd > 1 || s == n) { for (int i = s; i <= n; i++) { for (int j = 1; j <= arr[i]; j++) { res.append(chars[i]); } } return res; } int GCD = arr[s]; for (int i = s + 1; i <= n; i++) { GCD = gcd(GCD, arr[i]); } int end = arr[s] / GCD; int[] newArr = new int[n + 1]; for (int i = 1; i <= n; i++) { newArr[i] = arr[i] / GCD; } StringBuilder sbS = new StringBuilder(); for (int i = 1; i <= end; i++) { sbS.append(chars[s]); } StringBuilder others = Construct(newArr, s + 1); String left = others.toString(); String right = others.reverse().toString(); if (arr[s] % 2 == 0) { res.append(right); for (int t = 1; t <= GCD / 2; t++) { res.append(sbS); res.append(sbS); if (t != GCD / 2) { res.append(left); res.append(right); } else { res.append(left); } } } else { left = left.substring(0, left.length() / 2); right = new StringBuilder(left).reverse().toString(); res.append(right); for (int t = 1; t <= GCD; t++) { res.append(sbS); if (t != GCD) { res.append(left); res.append(right); } else { res.append(left); } } } return res; } void Solve() { FastScanner scan = new FastScanner(); PrintWriter out = new PrintWriter(System.out); n = scan.nextInt(); a = new int[n + 1]; chars = new char[n + 1]; chars[1] = 'a'; for (int i = 2; i <= n; i++) { chars[i] = (char) (chars[i - 1] + 1); } int odd = 0; for (int i = 1; i <= n; i++) { a[i] = scan.nextInt(); if (a[i] % 2 == 1) { odd++; } } int GCD = a[1]; for (int i = 2; i <= n; i++) { GCD = gcd(GCD, a[i]); } StringBuilder sb = new StringBuilder(); if (odd > 1) { out.println(0); } else { out.println(GCD); } sb = Construct(a, 1); out.println(sb); out.flush(); } public static void main(String[] args) { new Main().Solve(); } public static class FastScanner { BufferedReader br; StringTokenizer st; public FastScanner(String s) { try { br = new BufferedReader(new FileReader(s)); } catch (FileNotFoundException e) { e.printStackTrace(); } } public FastScanner() { br = new BufferedReader(new InputStreamReader(System.in)); } String nextToken() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } return st.nextToken(); } public boolean EOF() { if (st != null && st.hasMoreTokens()) { return false; } else { String line = null; try { line = br.readLine(); } catch (IOException e) { e.printStackTrace(); } if (line == null) return true; st = new StringTokenizer(line); return false; } } int nextInt() { return Integer.parseInt(nextToken()); } long nextLong() { return Long.parseLong(nextToken()); } double nextDouble() { return Double.parseDouble(nextToken()); } } }
相关文章推荐
- Codeforces Round #197 (Div. 2)
- Codeforces Round #198 (Div. 1)
- Codeforces 405E Codeforces Round #238 (Div. 2)E
- Codeforces 407C Codeforces Round #239 (Div. 1)C
- CodeForces 449A - Jzzhu and Chocolate
- CodeForces 449 B. Jzzhu and Cities
- Codeforces Round #265 (Div. 2)
- Codeforces #310 div2 C. Case of Matryoshkas
- 状态压缩DP codeforces 244 Problem C. The Brand New Function 和 codeforces 165 E. Compatible Numbers
- codeforces 16 Problem E fish
- Codeforces Round332 部分题解
- Codeforces round #247 for Div. 2
- Codeforces Round #246 (Div. 2)
- Codeforces #264(div 2)D.Gargari and Permutations
- Codeforces Round #236 (Div. 2)------A,B
- codeforces 257 div2 B
- Codeforces Gym100571A Cursed Query
- Codeforces Gym100342E Minima
- Codeforces Gym100342J Triatrip
- Codeforces Gym100286B Blind Walk (dfs)