[BZOJ1027][JSOI2007]合金

[JSOI2007]合金

Description
某公司加工一种由铁、铝、锡组成的合金。他们的工作很简单。首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同。然后,将每种原材料取出一定量,经过融解、混合,得到新的合金。新的合金的铁铝锡比重为用户所需要的比重。 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重。公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金。
Input
第一行两个整数m和n(m, n ≤ 500),分别表示原材料种数和用户需要的合金种数。第2到m + 1行,每行三个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种原材料中所占的比重。第m + 2到m + n + 1行,每行三个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种用户需要的合金中所占的比重。
Output
一个整数,表示最少需要的原材料种数。若无解,则输出–1。
Sample Input
10 10
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
Sample Output
5

Solution
首先前两维符合要求之后第三维自然符合,无视
两个材料能合成的所有合金在它们的连线的线段上
若干材料能合成的所有合金在它们的凸包内
那么我们要用最少的点构成的凸包囊括所有的要求点

枚举两个材料,如果所有合金在它们分割成的一个半平面里,就连一条有向边

然后就是最小环

Code

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

#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define MS(_, __) memset(_, __, sizeof(__))
#define MP make_pair
#define PB push_back
typedef long long ll;
typedef pair<int, int> PII;
template<typename T> inline void read(T &x){
    x = 0; T f = 1; char ch = getchar();
    while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
    while (isdigit(ch))  {x = x * 10 + ch - '0'; ch = getchar();}
    x *= f;
}

const int INF = 1e9;
const double eps = 1e-8;
struct Vec{
    double x, y;
    Vec() {}
    Vec(double _x, double _y) : x(_x), y(_y) {}
    inline double angle() const{ return atan2(y, x); }
    inline double len() const{ return sqrt(x*x+y*y); }
    inline Vec l_rot() const{ return Vec(-y, x); }
    inline Vec r_rot() const{ return Vec(y, -x); }
};
inline Vec operator + (const Vec &a, const Vec &b) { return Vec(a.x+b.x, a.y+b.y); }
inline Vec operator - (const Vec &a, const Vec &b) { return Vec(a.x-b.x, a.y-b.y); }
template<typename T> inline Vec operator * (const Vec &a, T b) { return Vec(a.x*b, a.y*b); }
template<typename T> inline Vec operator * (T a, const Vec &b) { return Vec(a*b.x, a*b.y); }
template<typename T> inline Vec operator / (const Vec &a, T b) { return Vec(a.x/b, a.y/b); }
inline double cross(const Vec &a, const Vec &b) { return a.x*b.y-a.y*b.x; }
inline double dot(const Vec &a, const Vec &b) { return a.x*b.x+a.y*b.y; }
typedef Vec Poi;
inline bool le(double x, double y) { return x-y<=eps; }
inline bool lt0(double x) { return x<-eps; }
inline bool gt0(double x) { return x>eps;}
inline bool eq0(double x) { return abs(x)<=eps; } 
inline bool between(Poi m, Poi l, Poi r) { return le(min(l.x,r.x),m.x)&&le(m.x,max(l.x,r.x)); }

int n, m;
Vec goal[510], given[510];
int g[510][510];
inline void spj(){
    if (n == 1){ bool flag = true;
        rep(i, 1, m) if (goal[i].x != given[1].x || goal[i].y != given[1].y) flag = false;
        puts(flag ? "1" : "-1");
        exit(0);
    }
}
int main(){
    read(n); read(m);

    rep(i, 1, n) scanf("%lf%lf%*lf", &given[i].x, &given[i].y);
    rep(i, 1, m) scanf("%lf%lf%*lf", &goal[i].x, &goal[i].y);
    spj();
    rep(i, 1, n) rep(j, 1, n) g[i][j] = INF;
    rep(dot1, 1, n) rep(dot2, dot1+1, n){ 
        Vec p = given[dot1]-given[dot2]; bool flag1 = false, flag2 = false, flag3 = false;
        rep(dot3, 1, m){
            double t = cross(p, goal[dot3]-given[dot2]);
            if (lt0(t)) flag1 = true;
            if (gt0(t)) flag2 = true;
            if (eq0(t) && gt0(dot(goal[dot3]-given[dot2], goal[dot3]-given[dot1]))) flag3 = true;
            if ((flag1 && flag2) || flag3) break;
        }
        if (flag1 && flag2) continue; if (flag3) continue;
        if (flag1) g[dot1][dot2] = 1; 
        else if (flag2) g[dot2][dot1] = 1;
        else g[dot1][dot2] = g[dot2][dot1] = 1;
    }

    int ans = INF;
    rep(k, 1, n) rep(i, 1, n) rep(j, 1, n) g[i][j] = min(g[i][j], g[i][k]+g[k][j]);
    rep(i, 1, n) ans = min(ans, g[i][i]);
    if (ans > n) puts("-1"); else printf("%d\n", ans);

    return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值