【BZOJ】1027: [JSOI2007]合金(凸包+floyd)
http://www.lydsy.com/JudgeOnline/problem.php?id=1027
题意:$n$种材料,$m$种需求。每种材料有三个属性,给出三个属性的含量(和为1),问能否通过这$n$种材料合成$m$种需求的材料。($n, m \le 500$)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const double eps=1e-6;
int dcmp(double x) { return abs(x)<eps?0:(x<0?-1:1); }
struct ipt { double x, y; ipt(double _x=0, double _y=0) : x(_x), y(_y) {} };
bool operator== (ipt &a, ipt &b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; }
double icross(ipt &a, ipt &b, ipt &c) {
static double x1, x2, y1, y2;
x1=a.x-c.x; y1=a.y-c.y;
x2=b.x-c.x; y2=b.y-c.y;
return x1*y2-x2*y1;
}
double idot(ipt &a, ipt &b, ipt &c) {
static double x1, x2, y1, y2;
x1=a.x-c.x; y1=a.y-c.y;
x2=b.x-c.x; y2=b.y-c.y;
return x1*x2+y1*y2;
}
bool cmp(const ipt &a, const ipt &b) { return a.x==b.x?a.y<b.y:a.x<b.x; }
void tu(ipt *p, ipt *s, int n, int &top) {
sort(p, p+n, cmp);
top=-1;
rep(i, n) {
while(top>0 && dcmp(icross(p[i], s[top], s[top-1]))>=0) --top;
s[++top]=p[i];
}
static int k;
k=top;
for3(i, n-2, 0) {
while(top>k && dcmp(icross(p[i], s[top], s[top-1]))>=0) --top;
s[++top]=p[i];
}
if(n>1) --top;
++top;
}
bool PonS(ipt &a, ipt &p1, ipt &p2) { if(a==p1 || a==p2) return true; return dcmp(icross(a, p1, p2))==0 && dcmp(idot(p1, p2, a))<0; } const int N=505, oo=~0u>>2;
int d[N][N], n, m, ans=oo;
ipt t[N], a[N], b[N];
bool checktu() {
rep(i, n) rep(j, m) if(dcmp(icross(b[j], a[i], a[i+1]))<0) return 0;
return 1;
}
bool check(ipt &x, ipt &y) {
rep(i, m) if(dcmp(icross(b[i], x, y))<0) return 0;
return 1;
}
bool spj() {
int flag;
rep(i, n) { flag=1; rep(j, m) if(!(a[i]==b[j])) { flag=0; break; } if(flag) { puts("1"); return 1; } }
rep(i, n) for1(j, i+1, n-1) {
flag=1;
rep(k, m) if(!PonS(b[k], a[i], a[j])) { flag=0; break; }
if(flag) { puts("2"); return 1; }
}
return 0;
} int main() {
read(n); read(m); double tt;
rep(i, n) scanf("%lf%lf%lf", &t[i].x, &t[i].y, &tt);
rep(i, m) scanf("%lf%lf%lf", &b[i].x, &b[i].y, &tt);
tu(t, a, n, n); a[n]=a[0];
if(!checktu()) { puts("-1"); return 0; }
if(spj()) return 0;
rep(i, n) rep(j, n) d[i][j]=oo;
rep(i, n) rep(j, n) if(i!=j) { if(check(a[i], a[j])) d[i][j]=1; else if(j>i) break; }
rep(k, n) rep(i, n) rep(j, n) d[i][j]=min(d[i][j], d[i][k]+d[k][j]);
rep(i, n) ans=min(ans, d[i][i]);
printf("%d\n", ans<=2?-1:ans);
return 0;
}
没special judge wa了一发好蛋疼...
首先这题大概和黑书上的差不多...由于知道任意两种材料就能得到第三种材料的含量,所以可以忽略第三种含量...
首先来看,如果有两种材料,那么能合成的材料一定在这个线段上,证明很简单...
假设材料A和B,要合成材料C,将他们材料的含量放到二维坐标系上(x轴为材料1,y轴为材料2)
假设用了a的A,则用了1-a的B,有
$$
\begin{align}
aX_A+(1-a)X_B & = X_C \\
aY_A+(1-a)Y_B & = Y_C \\
0<=a<=1 \\
\end{align}
$$
显然了吧...
然后考虑多个点,因为两两之间的点都是取得到的,那么这些两两之间的点又能连接起来,重复下去,显然最终可以取到的点是这个点集的凸包内的点..
//upd:wiki了一下...这个就是凸包的线性意义...
//即
$$S=\{\sum_{x_i \in X} t_ix_i | t_i \in [0, 1] \} $$
因此容易判断-1的情况(特判一个点取完所有和两个点的线段取完所有,要不然后边凸包会错...)
然后求最少的点形成凸包,很容易想到吧...我在课堂上也yy出来了...
凸包上的点如果所有该包围的点都在左边(右手方向),那么这两个点是可以连接与右手方向的剩余原凸包上的点形成凸包的...证明很简单...凸包上任意的点的子集都是凸包(当然空集除外..)...
然后我们对这些点对连边...找最小长度的环即可....如此弱的数据随便来floyd...
【BZOJ】1027: [JSOI2007]合金(凸包+floyd)的更多相关文章
- BZOJ 1027 JSOI2007 合金 计算几何+Floyd
题目大意:给定一些合金,选择最少的合金,使这些合金能够按比例合成要求的合金 首先这题的想法特别奇异 看这题干怎么会想到计算几何 并且计算几何又怎么会跟Floyd挂边 好强大 首先因为a+b+c=1 所 ...
- BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)
题解就看这位仁兄的吧-不过代码还是别看他的了- 同样的方法-我200ms,他2000ms. 常数的幽怨- CODE #include <bits/stdc++.h> using names ...
- bzoj 1027 [JSOI2007]合金(计算几何+floyd最小环)
1027: [JSOI2007]合金 Time Limit: 4 Sec Memory Limit: 162 MBSubmit: 2970 Solved: 787[Submit][Status][ ...
- BZOJ 1027 [JSOI2007]合金
1027: [JSOI2007]合金 Time Limit: 4 Sec Memory Limit: 162 MBSubmit: 2605 Solved: 692[Submit][Status][ ...
- bzoj 1027: [JSOI2007]合金【凸包+Floyd】
参考:https://www.cnblogs.com/zhuohan123/p/3237246.html 因为一c可以由1-a-b得出,所以删掉c,把a,b抽象成二维平面上的点.首先考虑一个客户需求能 ...
- 【BZOJ 1027】 (凸包+floyd求最小环)
[题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...
- [bzoj 1027][JSOI2007]合金(解析几何+最小环)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1027 分析: 首先因为一个合金的和为1,所以考虑2个材料合金能否合成一个需求合金的时候 ...
- BZOJ 1027 [JSOI2007]合金 ——计算几何
我们可以把每一种金属拆成一个二维向量,显然第三维可以计算出来,是无关的. 我们只需要考虑前两维的情况,显然可以构成点集所形成的凸包内. 然后我们枚举两两的情况,然后可以发现如果所有的点都在一侧是可以选 ...
- 1027: [JSOI2007]合金 - BZOJ
Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的 ...
随机推荐
- Centos下安装mysql 总结
一.MySQL安装 Centos下安装mysql 请点开:http://www.centoscn.com/CentosServer/sql/2013/0817/1285.html 二.MySQL的几个 ...
- DrawText
该函数在指定的矩形里写入格式化的正文,根据指定的方法对正文格式化(扩展的制表符,字符对齐.折行等). int DrawText(HDC hDC, // 设备描述表句柄 LPCTSTR lpStri ...
- 对Excel文件的操作
①.将文件设为“嵌入的资源”,Template修改不灵活:Stream stream=this.GetType().Assembly.GetManifestResourceStream(Templat ...
- java调用matlab函数
如何将实验结果在matlab中可视化呢,下面使用java语言编程,调用matlab中的函数: 本人安装的是Matlab7.11.0 (R2010a)和 Eclipse 4.2 : 1)首先设置环境变量 ...
- .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程
原文来自VAllen cnblogs 一.使用教程1.解压后,双击Reflector.exe,如果有选择默认版本的.Net Framework,根据需要选择即可.你选择的版本不同则出现的默认程序集也不 ...
- 【JAVA、C++】LeetCode 021 Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing ...
- 22.python笔记之web框架
一.web框架本质 1.基于socket,自己处理请求 #!/usr/bin/env python3 #coding:utf8 import socket def handle_request(cli ...
- CodeForces - 417B (思维题)
Crash Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Status ...
- windows8输入法终极完美修复
现在WIN8正式版出现以来,win8的用户越来越多,毕竟是新系统,BUG肯定是有的,现在小编就为大家解决一个大BUG. 输入法BUG: 现象:1.删除系统输入法,重启后无法调出输入法; 2.卸载用户安 ...
- 大神的游戏(codevs 1353)
题目描述 Description 在那遥远的机房,有一片神奇的格子.为了方便起见,我们编号为1~n.传说只要放入一些卡片,就能实现愿望.卡片一共有m种颜色,但是相邻的格子间不能放入相同颜色的卡片.只要 ...