[Contest]2017 ACM/ICPC Asia Regional Qingdao Online(施工中...)

1001 Apple

题意

给定一个三角形,判断一个点是否在其外接圆外。

题解

考虑求出外接圆圆心,简单比较即可。
根据计算几何知识,我们知道三角形三个顶点分别为$(x_1,y_1)(x_2,y_2)(x_3,y_3)$,则外心为$(\frac{\begin{vmatrix}
x_12+y_12 & y_1 & 1 \newline
x_22+y_22 & y_2 & 1 \newline
x_32+y_32 & y_3 & 1
\end{vmatrix}}{2\times\begin{vmatrix}
x_1 & y_1 & 1 \newline
x_2 & y_2 & 1 \newline
x_3 & y_3 & 1
\end{vmatrix}},\frac{\begin{vmatrix}
x_1 & x_12+y_12 & 1 \newline
x_2 & x_22+y_22 & 1 \newline
x_3 & x_32+y_32 & 1
\end{vmatrix}}{2\times\begin{vmatrix}
x_1 & y_1 & 1 \newline
x_2 & y_2 & 1 \newline
x_3 & y_3 & 1
\end{vmatrix}})$。
$PS:C++$爆了精度,我是用$Java$的$BigDecimal$类过的。

代码

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {

    public static BigDecimal Sqr(BigDecimal x) {
        return x.multiply(x);
    }
        
    public static BigDecimal Distance(BigDecimal x1, BigDecimal y1, BigDecimal x2, BigDecimal y2) {
        return Sqr(x1.subtract(x2)).add(Sqr(y1.subtract(y2)));
    }
    
    public static BigDecimal Determinant(BigDecimal a, BigDecimal b, BigDecimal c, BigDecimal d, BigDecimal e, BigDecimal f, BigDecimal g, BigDecimal h, BigDecimal i) {
        BigDecimal p1 = a.multiply(e).multiply(i);
        BigDecimal p2 = b.multiply(f).multiply(g);
        BigDecimal p3 = c.multiply(d).multiply(h);
        BigDecimal n1 = c.multiply(e).multiply(g);
        BigDecimal n2 = b.multiply(d).multiply(i);
        BigDecimal n3 = a.multiply(f).multiply(h);
        return p1.add(p2).add(p3).subtract(n1).subtract(n2).subtract(n3);
    }
    
    public static String Circumcenter(BigDecimal x1, BigDecimal y1, BigDecimal x2, BigDecimal y2, BigDecimal x3, BigDecimal y3, BigDecimal xp, BigDecimal yp) {
        BigDecimal one = new BigDecimal("1");
        BigDecimal two = new BigDecimal("2");
        BigDecimal xc = Determinant(Sqr(x1).add(Sqr(y1)), y1, one, Sqr(x2).add(Sqr(y2)), y2, one, Sqr(x3).add(Sqr(y3)), y3, one);
        xc = xc.divide(Determinant(x1, y1, one, x2, y2, one, x3, y3, one).multiply(two));
        BigDecimal yc = Determinant(x1, Sqr(x1).add(Sqr(y1)), one, x2, Sqr(x2).add(Sqr(y2)), one, x3, Sqr(x3).add(Sqr(y3)), one);
        yc = yc.divide(Determinant(x1, y1, one, x2, y2, one, x3, y3, one).multiply(two));
        BigDecimal r = Sqr(x1.subtract(xc)).add(Sqr(y1.subtract(yc)));
        BigDecimal d = Sqr(xp.subtract(xc)).add(Sqr(yp.subtract(yc)));
        return d.compareTo(r) == 1 ? "Accepted" : "Rejected";
    }
    
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        int T = Integer.parseInt(reader.nextLine());
        while ((T--) > 0) {
            String string = reader.nextLine();
            String pos[] = string.split(" ");

            BigDecimal x1 = new BigDecimal(pos[0]); BigDecimal y1 = new BigDecimal(pos[1]);
            BigDecimal x2 = new BigDecimal(pos[2]); BigDecimal y2 = new BigDecimal(pos[3]);
            BigDecimal x3 = new BigDecimal(pos[4]); BigDecimal y3 = new BigDecimal(pos[5]);
            BigDecimal x  = new BigDecimal(pos[6]); BigDecimal y  = new BigDecimal(pos[7]);
            
            System.out.println(Circumcenter(x1, y1, x2, y2, x3, y3, x, y));
        }
        reader.close();
    }
}

1002 Bomberman

题意

题解

代码


1003 The Dominator of Strings

题意

求若干串中一个“支配串”使得其他串都是它的子串。

题解

首先“支配串”的一定是长度最大的那一个。然后我们考虑对于每个串在“支配串”中$string::find$即可。
数据太水让我给水过去了,题目没有给出串总数的范围,复杂度玄学......

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<string> s;

int main() {
    ios::sync_with_stdio(false);
    int T; cin >> T;
    while (T--) {
        int n; cin >> n;
        int len = 0; string dom = ""; s.clear();
        for (int i = 1; i <= n; i++) {
            string str; cin >> str; s.push_back(str);
            if (str.size() > len) len = str.size(), dom = str;
        }
        bool flag = 1;
        for (auto str : s) {
            if (dom.find(str) != str.npos) continue;
            else {
                flag = 0; break;
            }
        }
        cout << (flag ? dom : "No") << "\n";
    }
    return 0;
}

1004 The Intersection

题意

题解

代码


1005 King's Visit

题意

题解

代码


1006 Pythagoras

题意

题解

代码


1007 Zuma

题意

题解

代码


1008 Chinese Zodiac

题意

给定两个人的生肖,第一个人比第二个人大,求年龄差最小是多少。

题解

暴力。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

inline int read() {
    int s = 1, x = 0; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') s = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return s * x;
}

map<string, int> sgn;

int main() {
    sgn["rat"] = 0;
    sgn["ox"] = 1;
    sgn["tiger"] = 2;
    sgn["rabbit"] = 3;
    sgn["dragon"] = 4;
    sgn["snake"] = 5;
    sgn["horse"] = 6;
    sgn["sheep"] = 7;
    sgn["monkey"] = 8;
    sgn["rooster"] = 9;
    sgn["dog"] = 10;
    sgn["pig"] = 11;
    int T; cin >> T;
    while (T--) {
        string a1, a2;
        cin >> a1 >> a2;
        cout << (a1 == a2 ? 12 : (sgn[a2] - sgn[a1] + 12) % 12) << endl;
    }
    return 0;
}

1009 Smallest Minimum Cut

题意

求有向图最小割的最少边数。

题解

这不是HDOJ原题么?......
我们考虑两种方法:

  • 第一种是跑两遍最大流,第一遍最大流之后把满流量的边容量$+1$,不是满流量的边容量改为$INF$,再跑第二遍最大流即为答案。因为容易证明:第一遍最大流之后满流量的边是最小割上的边。
  • 第二种是建边时扩大边权$w'=m\times w+1$,这样求出来的最大流为$\frac{flow}{m}$,最小割最少边数为$flow\mod m$。因为容易证明:原图中最小割的边满流量$w$,新图中也一定能满流量$m\times w$,而多余的$1$容量,相当于第一种方法里面跑的第二遍最大流。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read() {
    int s = 1, x = 0; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') s = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return s * x;
}

const int N = 209;
const int M = 4009;
const int INF = 0x3f3f3f3f;
int n, m, s, t, tot;
int head[N];
struct Edge {
    int v, nxt, cap, flw;
} e[M];
void addEdge(int u, int v, int cap) {
    e[tot].v = v; e[tot].nxt = head[u]; e[tot].cap = cap; e[tot].flw = 0; head[u] = tot++;
    e[tot].v = u; e[tot].nxt = head[v]; e[tot].cap = 0; e[tot].flw = 0; head[v] = tot++;
}
int lvl[N], gap[N];
void bfs() {
    memset(lvl, -1, sizeof(lvl));
    memset(gap, 0, sizeof(gap));
    lvl[t] = 0; gap[ lvl[t] ]++;
    queue<int> q; q.push(t);
    while(!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = head[u]; i != -1; i = e[i].nxt) {
            int v = e[i].v;
            if (lvl[v] != -1) continue;
            lvl[v] = lvl[u] + 1; gap[ lvl[v] ]++;
            q.push(v);
        }
    }
}
int pre[N], cur[N];
int ISAP() {
    bfs();
    memset(pre, -1, sizeof(pre));
    memcpy(cur, head, sizeof(head));
    int u = pre[s] = s;
    int flw = 0, aug = INF;
    gap[0] = n;
    while (lvl[s] < n) {
        bool flag = false;
        for (int &i = cur[u]; i != -1; i = e[i].nxt) {
            int v = e[i].v;
            if (e[i].cap != e[i].flw && lvl[u] == lvl[v] + 1) {
                flag = true; pre[v] = u; u = v;
                aug = min(aug, e[i].cap - e[i].flw);
                if (v == t) {
                    flw += aug;
                    for (u = pre[v]; v != s; v = u, u = pre[u]) {
                        e[ cur[u] ].flw += aug;
                        e[ cur[u] ^ 1 ].flw -= aug;
                    }
                    aug = INF;
                }
                break;
            }
        }
        if (flag) continue;
        int minLevel = n;
        for (int i = head[u]; i != -1; i = e[i].nxt) {
            int v = e[i].v;
            if (e[i].cap != e[i].flw && lvl[v] < minLevel) {
                minLevel = lvl[v];
                cur[u] = i;
            }
        }
        if (--gap[ lvl[u] ] == 0) break;
        lvl[u] = minLevel + 1;  gap[ lvl[u] ]++; u = pre[u];
    }
    return flw;
}
int main() {
    int T = read();
    while (T--) {
        n = read(), m = read(), s = read(), t = read(), tot = 0;
        memset(head, -1, sizeof(head));
        for (int i = 1; i <= m; i++) {
            int u = read(), v = read(), w = read();
            addEdge(u, v, w * m + 1);
        }
        printf("%d\n", ISAP() % m);
    }
    return 0;
}

1010 Brute Force Sorting

题意

题解

代码


1011 A Cubic number and A Cubic Number

题意

判断一个素数$p$能否表示成立方差。

题解

我们考虑$p=a3-b3=(a-b)(a2+ab+b2)$,要满足$p$是素数,必须有$a-b=1$。因此$p=(b+1)2+(b+1)b+b2=3b^2+3b+1$,$p-1=3b(b+1)$。直接枚举$b$即可。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

inline ll read() {
    ll s = 1, x = 0; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') s = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return s * x;
}
inline bool check(ll p) {
    p -= 1;
    if (p % 3 != 0) return 0;
    p /= 3;
    for (ll a = 1; a * (a + 1) <= p; a++) {
        if (a * (a + 1) == p) return 1; 
    }
    return 0;
}
int main() {
    ll T = read();
    while (T--) {
        ll p = read();
        puts(check(p) ? "YES" : "NO");
    }
    return 0;
}
posted @ 2017-09-18 00:11  jstztzy  阅读(269)  评论(0编辑  收藏  举报