1. 程式人生 > >Codeforces 851A/B/C

Codeforces 851A/B/C

-a font 必要條件 for efi ces bool rcc 空間

A. Arpa and a research in Mexican wave

傳送門:http://codeforces.com/contest/851/problem/A

水題,參考程序如下:

#include <stdio.h>

int main(void)
{
    int n, k, t;
    scanf("%d%d%d", &n, &k, &t);
    if (t <= k) printf("%d\n", t);
    else if (t <= n) printf("%d\n", k);
    else printf("%d\n
", n + k - t); return 0; }

B. Arpa and an exam about geometry

傳送門:http://codeforces.com/contest/851/problem/B

本題是一個平面幾何問題。

平面上有3個點A,B,C,坐標分別為(ax,ay),(bx,by),(cx,cy)。現以平面上一點P為中心,將點A,B,C旋轉角度θ,旋轉後的點分別為A’,B’,C’。試問:是否存在點P和角度θ,使得“點A’與點B重合,點B’與點C重合”?

以上條件等價於:存在點P和角度θ,使得|PA|=|PB|=|PC|,且∠APB=BPC=θ”。

考慮點A,B,C

的幾何關系:

A,B,C位於同一條直線上,則不存在滿足條件的點P和角度θ

A,B,C不位於同一條直線上,若存在滿足條件的點P和角度θ,則由等價條件可知:△APB≌△BPC,因此|AB|=|BC|

因此,題中條件成立,當且僅當A,B,C不共線,且|AB|=|BC|”。

A,B,C三點共線的一個充分條件是直線ABBC的斜率相等,但這是一個充分不必要條件。

A,B,C三點共線的一個充分必要條件可以通過向量形式給出:

向量α1=(Δx1y1)T,α2=(Δx2y2)T,其中Δx1=bx-axy1=by-ayx2=cx-bxy2=cy-by

若向量α1α2共線,則向量組α

1,α2線性相關。設A=(α1,α2),則detA=0。

$$\det A=\left|\begin{matrix}\Delta x_1&\Delta x_2\\\Delta y_1&\Delta y_2\end{matrix}\right|=0\Leftrightarrow\Delta x_1\cdot\Delta y_2=\Delta x_2\cdot\Delta y_1$$

因此,A,B,C三點共線的一個充分必要條件是Δx1·Δy2x2·Δy1。參考程序如下:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int ax, ay, bx, by, cx, cy;
    scanf("%d%d%d%d%d%d", &ax, &ay, &bx, &by, &cx, &cy);
    int64_t dx1 = bx - ax, dy1 = by - ay;
    int64_t dx2 = cx - bx, dy2 = cy - by;
    if (dx1 * dy2 == dx2 * dy1) printf("No\n");
    else {
        if (dx1 * dx1 + dy1 * dy1 == dx2 * dx2 + dy2 * dy2) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

C. Five Dimensional Points

傳送門:http://codeforces.com/contest/851/problem/C

本題是一個空間幾何問題。

在五維空間中,有n個不同的點P1,P2,...,PnPi的坐標為(ai,bi,ci,di,ei)。現有定義:點Abad,當且僅當存在不同於點A的點B和點C,使得向量ABAC的夾角為銳角;否則,點Agood。求{1,2,...,n}的子集S,使得對於S中的每一個元素i,均有Pigood。

向量的夾角按照以下公式計算:$<\boldsymbol{a},\boldsymbol{b}>=\arccos \frac{\boldsymbol{a}\cdot \boldsymbol{b}}{|\boldsymbol{a}||\boldsymbol{b}|}$

而對於向量a=(a1,a2,...,ak),b=(b1,b2,...,bk),內積a·b的計算公式為: $\boldsymbol{a}\cdot\boldsymbol{b}=\sum_{j=1}^{k}{a_{j}b_{j}}$

本題直接模擬即可,時間復雜度為O(n3)。

參考程序如下:

#include <stdio.h>
#include <stdbool.h>
#define MAX_N 1000

typedef int quint[5];

quint p[MAX_N], v[MAX_N][MAX_N];
int good[MAX_N];

int main(void)
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        for (int k = 0; k < 5; k++) {
            scanf("%d", &p[i][k]);
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < 5; k++) {
                v[i][j][k] = p[j][k] - p[i][k];
            }
        }
    }
    int cnt = 0;
    for (int t = 0; t < n; t++) {
        bool flag = false;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                int inp = 0;
                for (int k = 0; k < 5; k++) {
                    inp += v[t][i][k] * v[t][j][k];
                }
                if (inp > 0) {
                    flag = true;
                    break;
                }
            }
        }
        if (!flag) {
            good[cnt++] = t + 1;
        }
    }
    printf("%d\n", cnt);
    for (int i = 0; i < cnt; i++) {
        printf("%d\n", good[i]);
    }
    return 0;
}

Codeforces 851A/B/C