http://acm.timus.ru/problem.aspx?space=1&num=1130
题意
出n个向量,长度均 ≤L ,问能否通过添加 + or − 号,使得求和以后长度 ≤2√L
题解
通过画图,可以发现,任意三个长度
≤L
的向量,通过适当的
+ or −
,其中必有两个可以凑出
≤L
的一个新向量。
如此做,最后剩下两个,此时再添加
+ or −
,必能凑出长度
≤2√L
的向量
code
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
typedef long long LL;
const int maxn = 10010;
struct Point {
int x, y;
Point() { }
Point(int x, int y) : x(x), y(y) { }
} A[maxn << 1];
Point operator +(const Point& A, const Point& B) { return Point(A.x+B.x, A.y+B.y); }
Point operator -(const Point& A, const Point& B) { return Point(A.x-B.x, A.y-B.y); }
int Length2(const Point& A) { return A.x * A.x + A.y * A.y; }
int N, n, L;
int sk[maxn], tp;
int tot;
int st[maxn << 1], lk[maxn << 1], b[maxn << 1], c[maxn << 1];
void addedge(int u, int v, int w) {
lk[++ tot] = st[u]; b[tot] = v; c[tot] = w; st[u] = tot;
}
char opt[maxn];
void dfs(int u, char p) {
if (u < N) opt[u] = p;
for (int i = st[u]; i; i = lk[i])
dfs(b[i], c[i] ? (p == '+' ? '-' : '+') : p);
}
void solve() {
scanf("%d%d", &N, &L); L *= L;
for (int i = 0; i < N; ++ i)
scanf("%d%d", &A[i].x, &A[i].y);
tp = 0;
for (int i = 0; i < N; ++ i) sk[tp ++] = i;
n = N;
while (tp > 1) {
int v1 = sk[tp-1], v2 = sk[tp-2];
if (tp > 2) {
int v3 = sk[tp-3]; tp -= 3;
if (Length2(A[v1]+A[v2]) <= L) { A[n ++] = A[v1]+A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 0); continue; }
if (Length2(A[v1]-A[v2]) <= L) { A[n ++] = A[v1]-A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 1); continue; }
std::swap(v2, v3);
if (Length2(A[v1]+A[v2]) <= L) { A[n ++] = A[v1]+A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 0); continue; }
if (Length2(A[v1]-A[v2]) <= L) { A[n ++] = A[v1]-A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 1); continue; }
std::swap(v1, v3);
if (Length2(A[v1]+A[v2]) <= L) { A[n ++] = A[v1]+A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 0); continue; }
if (Length2(A[v1]-A[v2]) <= L) { A[n ++] = A[v1]-A[v2]; sk[tp ++] = v3; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 1); continue; }
} else {
tp -= 2;
if (Length2(A[v1]+A[v2]) <= L*2) { A[n ++] = A[v1]+A[v2]; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 0); continue; }
if (Length2(A[v1]-A[v2]) <= L*2) { A[n ++] = A[v1]-A[v2]; sk[tp ++] = n-1; addedge(n-1, v1, 0); addedge(n-1, v2, 1); continue; }
}
// assert(0);
}
// assert(Length2(A[0]) <= L*2);
puts("YES");
dfs(n-1, '+');
for (int i = 0; i < N; ++ i) putchar(opt[i]);
putchar('\n');
}
int main() {
// freopen("G.in", "r", stdin);
// freopen("G_2.out", "w", stdout);
solve();
// for(;;);
return 0;
}