题意:
给出四个点的坐标(每个点的坐标值小于等于1,000,000,000,000),问最后一个点是否在前三个点组成的三角形的外接圆内,是输出Accept,否输出Rejected
解题思路:
题意很好理解,就是判断一个点是否在一个圆内,或者说一个点到圆心的距离是否大于半径,关键是大整数和精度问题,题解中给出了java的解法。
设x0,y0为圆心,有圆心到三个顶点的距离相等,列出如下两个式子:
(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0) = (x2-x0)*(x2-x0)+(y2-y0)*(y2-y0).
(x2-x0)*(x2-x0)+(y2-y0)*(y2-y0) = (x3-x0)*(x3-x0)+(y3-y0)*(y3-y0).
化简可得:
2(x2-x1)x0 + 2(y2-y1)y0 = x2^2 + y2^2 - x1^2 - y1^2.
2(x3-x2)x0 + 2(y3-y2)y0 = x3^2 + y3^2 - x2^2 - y2^2.
令a1 = 2*(x2-x1);
b1 = 2*(y2-y1);
c1 = x2^2 + y2^2 - x1^2 - y1^2;
a2 = 2*(x3-x2);
b2 = 2*(y3-y2);
c2 = x3^2 + y3^2 - x2^2 - y2^2;
则
a1*x0 + b1*y0 = c1;
a2*x0 + b2*y0 = c2;
根据克莱姆法则(具体参见记法2)可得
x0 = (c1*b2 - b1*c2)/(a1*b2 - b1*a2);
y0 = (a1*c2 - c1*a2)/(a1*b2 - b1*a2);
由两点间距离公式得
r = (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
d = (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);(x-x0)*(x-x0)+(y-y0)*(y-y0);(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)
由于涉及到大整数和高精度,使用Java中的BidDecimal代码如下:
1 import java.math.BigDecimal; 2 import java.util.Scanner; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 Scanner in = new Scanner(System.in); 8 int T = in.nextInt(); 9 while(T-- > 0) { 10 BigDecimal x1 = in.nextBigDecimal(); 11 BigDecimal y1 = in.nextBigDecimal(); 12 BigDecimal x2 = in.nextBigDecimal(); 13 BigDecimal y2 = in.nextBigDecimal(); 14 BigDecimal x3 = in.nextBigDecimal(); 15 BigDecimal y3 = in.nextBigDecimal(); 16 BigDecimal x = in.nextBigDecimal(); 17 BigDecimal y = in.nextBigDecimal(); 18 19 BigDecimal a1 = x2.subtract(x1).multiply(BigDecimal.valueOf(2)); 20 BigDecimal b1 = y2.subtract(y1).multiply(BigDecimal.valueOf(2)); 21 BigDecimal c1 = x2.pow(2).add(y2.pow(2)).subtract(x1.pow(2)).subtract(y1.pow(2)); 22 23 BigDecimal a2 = x3.subtract(x2).multiply(BigDecimal.valueOf(2)); 24 BigDecimal b2 = y3.subtract(y2).multiply(BigDecimal.valueOf(2)); 25 BigDecimal c2 = x3.pow(2).add(y3.pow(2)).subtract(x2.pow(2)).subtract(y2.pow(2)); 26 27 BigDecimal x0 = b2.multiply(c1).subtract(b1.multiply(c2)).divide(a1.multiply(b2).subtract(b1.multiply(a2))); 28 BigDecimal y0 = a1.multiply(c2).subtract(c1.multiply(a2)).divide(a1.multiply(b2).subtract(b1.multiply(a2))); 29 30 BigDecimal r = x1.subtract(x0).pow(2).add(y1.subtract(y0).pow(2)); 31 BigDecimal d = x.subtract(x0).pow(2).add(y.subtract(y0).pow(2)); 32 if(1 == d.compareTo(r)) 33 System.out.println("Accepted"); 34 else 35 System.out.println("Rejected"); 36 } 37 } 38 39 }
HDU 6208 The Dominator of Strings
题意:
给出n个串,问是否存在一个串能够包含这n个串。
解题思路:
AC自动机的模板题,注意输入字符串的数组开大一点就行了。
1 #include <cstdio> 2 #include <cstring> 3 4 const int K = 26; 5 const int maxn = 100000 + 10; 6 struct Node { 7 Node *ch[K], *fail; 8 int mc; 9 void clear(){ 10 memset(this, 0, sizeof(Node)); 11 } 12 }; 13 14 Node *que[maxn*2]; 15 struct AC { 16 Node nodes[maxn], *root, *sroot, *cur; 17 Node* newNode() { 18 cur->clear(); 19 return cur++; 20 } 21 void clear() { 22 cur = nodes; 23 sroot = newNode(); 24 root = newNode(); 25 root->fail = sroot; 26 for(int i = 0; i < K; i++) { 27 sroot->ch[i] = root; 28 } 29 sroot->mc = -1; 30 } 31 void insert(char *s) { 32 Node* t = root; 33 for(; *s; s++) { 34 int x = *s - 'a'; 35 if(t->ch[x] == NULL) 36 t->ch[x] = newNode(); 37 t=t->ch[x]; 38 } 39 t->mc++; 40 } 41 void build() { 42 int p = 0, q = 0; 43 que[q++] = root; 44 while(p != q) { 45 Node *t = que[p++]; 46 for(int i = 0; i < K; i++) { 47 if(t->ch[i]) { 48 t->ch[i]->fail = t->fail->ch[i]; 49 que[q++] = t->ch[i]; 50 } 51 else 52 t->ch[i] = t->fail->ch[i]; 53 } 54 } 55 } 56 int run(char *s) { 57 int ans = 0; 58 Node* t = root; 59 for(; *s; s++) { 60 int x = *s - 'a'; 61 t = t->ch[x]; 62 for(Node* u = t; u->mc != -1; u = u->fail) { 63 ans += u->mc; 64 u->mc = -1; 65 } 66 } 67 return ans; 68 } 69 }ac; 70 int n; 71 char s[100100], t[100110]; 72 int main() 73 { 74 int T; 75 scanf("%d", &T); 76 while(T--) { 77 scanf("%d", &n); 78 ac.clear(); 79 int maxl = 0; 80 memset(t, 0, sizeof(t)); 81 for(int i = 0; i < n; i++) { 82 scanf(" %s", s); 83 int len = strlen(s); 84 if(len > maxl) { 85 maxl = len; 86 strcpy(t, s); 87 } 88 ac.insert(s); 89 } 90 ac.build(); 91 92 if(ac.run(t) == n) 93 puts(t); 94 else 95 puts("No"); 96 } 97 return 0; 98 }
HDU 6216 A Cubic number and A Cubic Number
题意:
判断一个质数p,是否是两个立方数之差
解题思路:
由题(x^3 - y^3) = p
即(x - y) * (x^2 - 2*x*y + y^2) = p
由于p是质数,所以(x - y) = 1,即x = y + 1,代入原式得
3 * y * y + 3 * y + 1 = p
枚举10^6以内的y,对于每一个p搜索是否存在即可。
1 #include <cstdio> 2 typedef long long ll; 3 const ll maxn = 1e6 + 10; 4 ll ls[maxn]; 5 6 int main() 7 { 8 int T; 9 ll p; 10 for(ll i = 0; i < maxn; i++) { 11 ls[i] = 3 * i * i + 3 * i + 1; 12 } 13 scanf("%d", &T); 14 while(T--) { 15 scanf("%lld", &p); 16 bool f = 0; 17 int le = -1, ri = maxn; 18 while(ri - le > 1) { 19 int mid = (ri + le) >> 1; 20 if(p == ls[mid]) { 21 f = 1; 22 break; 23 } else if(p > ls[mid]) 24 le = mid; 25 else 26 ri = mid; 27 } 28 if(f) 29 puts("YES"); 30 else 31 puts("NO"); 32 } 33 return 0; 34 }
题意:
前提是女的比男的大,给出生肖,问两人的最小年龄差是多少
1 #include <cstdio> 2 #include <map> 3 #include <cstring> 4 #include <string> 5 #include <iostream> 6 using namespace std; 7 8 const string ls[12] = {"rat", "ox", "tiger", "rabbit", "dragon", "snake", "horse", "sheep", 9 "monkey", "rooster", "dog", "pig"}; 10 11 int main() 12 { 13 int T; 14 map<string, int> mp; 15 for(int i = 0; i < 12; i++) { 16 mp[ls[i]] = i + 1; 17 } 18 string a, b; 19 cin >> T; 20 while(T--) { 21 cin >> a >> b; 22 int c = mp[a]; 23 int d = mp[b]; 24 int ans = d - c; 25 26 if(ans <= 0) 27 ans += 12; 28 cout << ans <<endl; 29 } 30 return 0; 31 }