【BZOJ 1027】[JSOI2007]合金
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1027
【题意】
【题解】
因为和为1;
所以只要知道两个属性第三个属性就能用1减出来了;
然后把每个合金材料化为平面坐标上的二维坐标;
两个合金能够合成的新合金的坐标就在这两个合金的连线上。
你可以假设两个合金的量分别为a,b;
对于某一种物质
新的合金该物质的含量为
(ap1+bp2)/(a+b)
=q*p1+w*p2;
这里(q+w)=1
然后代入两点式可证新的点必然在其上.
所以两个合金能够合成的新的合金必然在它们的连线上.
然后有多个合金。
要求你把这些合金合成客户所需要的合金。
可以想象成两个点集S1和S2
要在S1中选择最少的点集;
使得这些点集形成的闭包包围住了整个S2;
(可以证明只要闭包包住了S2,则S2里面的点集都能得到);
然后用计算几何搞出来S1中任意两个点(i,j)是否S2整个在其左侧.
如果是的话在(i,j)之间连一条边,边权为1;
然后求最小环就是答案了;
这里get到了求最小环的新姿势。
然后这个程序漏了两种情况;
就是ans=1和ans=2的情况。
对于这两种情况是要特判的;
因为这两种情况不是一个闭包了(对应了一个点和一条线)
没办法用闭包涉及到。
所以要加上一个点和两个点的特判;
(很懒并没有加上)
数据很弱啊,不想加了。知道就好。
【完整代码】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int N = 510;
const int INF = 0x3f3f3f3f;
struct point
{
double x, y;
point operator -(const point z)
{
point re;
re.x = x - z.x;
re.y = y - z.y;
return re;
}
double operator * (const point z)
{
return x*z.y - y*z.x;
}
double operator ^ (const point z)
{
return x*z.x + y*z.y;
}
} a[N], b[N];
int m, n;
int d[N][N], f[N][N];
int ans = INF;
void input_data()
{
rei(m), rei(n);
double t;
rep1(i, 1, m)
{
ref(a[i].x), ref(a[i].y), ref(t);
}
rep1(i, 1, n)
{
ref(b[i].x), ref(b[i].y), ref(t);
}
}
void ga()
{
memset(d, 0x3f, sizeof d);
rep1(i,1,m)
rep1(j, 1, m)
{
int k;
for (k = 1; k <= n;k++)
{
double cross = (a[i] - b[k])*(a[j] - b[k]);
if (cross > 1e-7)
break;
if (fabs(cross) < 1e-7 && (a[i] - b[k] ^ a[j] - b[k]) > 1e-7)
break;
}
if (k == n + 1)
d[i][j] = 1;
}
}
void fl()
{
memcpy(f, d, sizeof f);
rep1(k,1,m)
rep1(i,1,m)
if (f[i][k]<INF)
rep1(j, 1, m)
{
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}
rep1(i, 1, m)
ans = min(ans, f[i][i]);
}
void o()
{
if (ans == INF)
{
puts("-1");
return;
}
printf("%d\n", ans);
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
ga();
fl();
o();
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
【BZOJ 1027】[JSOI2007]合金的更多相关文章
- 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]合金(解析几何+最小环)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1027 分析: 首先因为一个合金的和为1,所以考虑2个材料合金能否合成一个需求合金的时候 ...
- BZOJ 1027 JSOI2007 合金 计算几何+Floyd
题目大意:给定一些合金,选择最少的合金,使这些合金能够按比例合成要求的合金 首先这题的想法特别奇异 看这题干怎么会想到计算几何 并且计算几何又怎么会跟Floyd挂边 好强大 首先因为a+b+c=1 所 ...
- BZOJ 1027 [JSOI2007]合金 ——计算几何
我们可以把每一种金属拆成一个二维向量,显然第三维可以计算出来,是无关的. 我们只需要考虑前两维的情况,显然可以构成点集所形成的凸包内. 然后我们枚举两两的情况,然后可以发现如果所有的点都在一侧是可以选 ...
- bzoj 1027: [JSOI2007]合金【凸包+Floyd】
参考:https://www.cnblogs.com/zhuohan123/p/3237246.html 因为一c可以由1-a-b得出,所以删掉c,把a,b抽象成二维平面上的点.首先考虑一个客户需求能 ...
- BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)
题解就看这位仁兄的吧-不过代码还是别看他的了- 同样的方法-我200ms,他2000ms. 常数的幽怨- CODE #include <bits/stdc++.h> using names ...
- 【BZOJ】1027: [JSOI2007]合金(凸包+floyd)
http://www.lydsy.com/JudgeOnline/problem.php?id=1027 题意:$n$种材料,$m$种需求.每种材料有三个属性,给出三个属性的含量(和为1),问能否通过 ...
- 1027: [JSOI2007]合金 - BZOJ
Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的 ...
- bzoj千题计划123:bzoj1027: [JSOI2007]合金
http://www.lydsy.com/JudgeOnline/problem.php?id=1027 因为x+y+z=1,所以z=1-x-y 第三维可以忽略 将x,y 看做 平面上的点 简化问题: ...
随机推荐
- 基于ContentObserver来动态取消或加入屏幕超时任务
前面也说了.ContentObserver能够来监控数据库里某一项数据的变化,当然也能够同一时候监控多个数据项的变化. 笔者在项目中须要改动到屏幕超时的需求,比方在车载业务中,倒车事件发生的时候,是不 ...
- Project Euler 613 Pythagorean Ant(概率+积分)
题目链接:点击我打开题目链接 题目大意: 给你一只蚂蚁,它在一个 边长为 \(30-40-50\) 的直角三角形\((x,y)\)上,并且它在直角三角形中选择的位置和移动方向的概率都是相等的.问你这只 ...
- (转)如何启动或关闭数据库的归档(ARCHIVELOG)模式
转自:http://www.eygle.com/archives/2004/10/oracle_howtoeci.html Oracle数据库可以运行在2种模式下:归档模式(archivelog)和非 ...
- Linux下的lds链接脚本简介(三)
八. 内存区域命令 在默认情形下,连接器可以为section在程序地址空间内分配任意位置的存储区域.并通过输出section描述的> REGION属性显示地将该输出section限定于在程序地址 ...
- vue指令应用--实现输入框常见过滤功能
前端开发最常碰到的就是输入框,经常要做各种验证,本公司惯用的需求是直接屏蔽特定字符的输入,如禁止非数字输入,特殊符号输入,空格输入等,这些功能反复使用,做成指令的形式,直接调用,非常方便,上代码: 目 ...
- 切换根控制器UIApplication 主屏幕UIScreen 读取文件资源NSBundle
//主屏幕设为webView CGRect frame = [UIScreen mainScreen].applicationFrame; UIWebView *webView = [[[UIWebV ...
- 关于Android中设置闹钟的相对完善的解决方案
前些时候,有人在我「非著名程序员」微信公众号的后台问我有没有设置闹钟的demo,我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这 ...
- HDU 2577 How to Type DP也可以模拟
http://acm.hdu.edu.cn/showproblem.php?pid=2577 大意: 大家都打过字吧,现在有个有趣的问题:给你一串字符串,有大写有小写,要求你按键次数最少来输出它,输出 ...
- Linux与Windows间使用git
Linux与Windows间使用git Linux上架设git服务器,windows可以使用git从Linux上拉取/上传数据 windows使用工具:Git for Windows Linux上的用 ...
- 计算git树上随意两点的近期切割点。
1.git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比方: base'<--base<--A<--A' ^ | --- B<--B' 小米project师 ...