• 2017 ACM/ICPC Asia Regional Qingdao Online解题报告(部分)


    HDU 6206 Apple

    题意:

    给出四个点的坐标(每个点的坐标值小于等于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 }

     HDU 6213 Chinese Zodiac

    题意:

    前提是女的比男的大,给出生肖,问两人的最小年龄差是多少

     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 }
  • 相关阅读:
    协程的嵌套
    利用excl的数据源表,手动选择品牌,根据品牌自动出现品牌的品牌类型、品牌型号、单价、质量等信息。
    uniapp实现薪资区间范围选择
    html2canvas + jspdf 实现html导出pdf并加水印
    jq实现薪资区间值选择
    C/C++中的函数指针的写法
    linux系统find命令的一些使用技巧
    RunAsDate改变软件获取系统时间工具
    电子政务及安全研究报告
    数据转换位串字节数组
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/9768200.html
Copyright © 2020-2023  润新知