2017 Benelux Algorithm Programming Contest (BAPC 17) Solution
A - Amsterdam Distance
题意:极坐标系,给出两个点,求最短距离
思路:只有两种方式,取min 第一种,先走到0点,再走到终点 第二种,走到同一半径,再走过去
#include <bits/stdc++.h> using namespace std;
#define INF 0x3f3f3f3f const double PI = acos(-1.0); double n, m, r;
double n1, m1, n2, m2; inline double work1()
{
double dis1 = r * n1 / n;
double dis2 = r * n2 / n;
return dis1 + dis2;
} inline double work2()
{
double dis1 = r * (n2 - n1) / n;
double dis2 = fabs(m1 - m2) * r * n1 * PI/ (n * m);
return dis1 + dis2;
} int main()
{
while (scanf("%lf%lf%lf", &m, &n, &r) != EOF)
{
scanf("%lf%lf%lf%lf", &m1, &n1, &m2, &n2);
if (n1 > n2)
{
swap(n1, n2);
swap(m1, m2);
}
double ans = INF * 1.0;
ans = min(ans, work1());
ans = min(ans, work2());
printf("%.10f\n", ans);
}
return ;
}
B - Bearly Made It
留坑。
C - Collatz Conjecture
题意:给出n个数,求有多少个不同的区间gcd
思路:从头扫过去,每次扩展gcd,如果有重复的直接剪掉
因为假设扫到第i个的时候,有x个gcd 那么到第i个,这x个gcd 如果都被保留下来,那么第i个数一定要是这n个数的倍数,那么显然如果存在这样的数,那么当x > 30 的时候 早就爆 1e18 了 所以复杂度应该在 30 * (n) * log(n)
#include<bits/stdc++.h> using namespace std; #define N 500050 typedef long long ll; inline ll gcd(ll a, ll b)
{
return b == ? a : gcd(b, a % b);
} int n;
ll GCD[N];
ll num;
map<ll, int>mp; int main()
{
while(~scanf("%d" ,&n))
{
mp.clear();
int len = ;
for(int i = ; i <= n; ++i)
{
scanf("%lld", &num);
for(int j = ; j < len; ++j)
{
GCD[j] = gcd(GCD[j], num);
}
GCD[len++] = num;
sort(GCD, GCD + len);
int tmp = ;
for(int i = ; i< len; ++i)
{
mp[GCD[i]]++;
if(i == )
{
GCD[tmp++] = GCD[i];
continue;
}
if(GCD[i] == GCD[i - ]) continue;
else GCD[tmp++] = GCD[i];
}
len = tmp;
}
int ans = mp.size();
printf("%d\n",ans);
}
return ;
}
D - Detour
题意:给出n条路,每次选择的路都不选从这条路到0的最短路径上的路,求最后选的最短路径
思路:先从1反向跑最短路,然后删边,再从0正向跑
#include <bits/stdc++.h>
using namespace std; #define N 100010
#define M 1000010
#define ll long long
#define INFLL 0x3f3f3f3f3f3f3f3f struct Edge
{
int to, nx, flag;
ll w;
inline Edge() {}
inline Edge(int to, ll w, int nx, int flag) : to(to), w(w), nx(nx), flag(flag) {}
}edge[M << ]; int head[N], pos; inline void Init()
{
memset(head, -, sizeof head);
pos = ;
} inline void addedge(int u, int v, ll w)
{
edge[++pos] = Edge(v, w, head[u], ); head[u] = pos;
edge[++pos] = Edge(u, w, head[v], ); head[v] = pos;
} int n, m; struct node
{
int to; ll w;
inline node() {}
inline node(int to, ll w) : to(to), w(w) {}
inline bool operator < (const node &r) const
{
return w > r.w;
}
}; ll dist[N];
int pre[N];
bool used[N]; inline void Dijkstra(int st)
{
for (int i = ; i < n; ++i) dist[i] = INFLL, used[i] = false, pre[i] = -;
dist[st] = ;
priority_queue <node> q; q.emplace(st, );
while (!q.empty())
{
int u = q.top().to; q.pop();
used[u] = true;
for (int it = head[u]; ~it; it = edge[it].nx)
{
if (edge[it].flag) continue;
int v = edge[it].to; ll w = edge[it].w;
if (!used[v] && dist[u] + w < dist[v])
{
dist[v] = dist[u] + w;
pre[v] = u;
q.emplace(v, dist[v]);
}
}
}
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
ll w; Init();
for (int i = , u, v; i <= m; ++i)
{
scanf("%d%d%lld", &u, &v, &w);
addedge(u, v, w);
}
Dijkstra();
if (dist[] == INFLL)
{
puts("impossible");
continue;
}
for (int i = ; i < n; ++i)
{
for (int it = head[i]; ~it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == pre[i])
{
edge[it].flag = ;
break;
}
}
}
Dijkstra();
if (dist[] == INFLL)
{
puts("impossible");
continue;
}
vector <int> ans;
int it = ;
while (it != -)
{
ans.push_back(it);
it = pre[it];
}
reverse(ans.begin(), ans.end());
int len = ans.size();
printf("%d ", len);
for (int i = ; i < len; ++i) printf("%d%c", ans[i], " \n"[i == len - ]); }
return ;
}
E - Easter Eggs
留坑。
F - Falling Apart
水。
#include <bits/stdc++.h> using namespace std; int n;
int arr[]; int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
sort(arr + , arr + + n);
int ans[] = {, };
int flag = ;
for (int i = n; i >= ; --i)
{
ans[flag] += arr[i];
flag ^= ;
}
printf("%d %d\n", max(ans[], ans[]), min(ans[], ans[]));
}
return ;
}
G - Going Dutch
留坑。
H - Hoarse Horses
留坑。
I - Irrational Division
题意:给出n * m 的矩形,单位边长为1,黑白交替,Alice 只能一列一列取(从左往右),Bob只能一行一行取(从下往上),取到的分数为黑块-白块,求Alice 和 Bob 的最大分差,两人操作都最优
思路:可以找一下规律,偶数行 答案是0
奇数行 奇数列 答案是1
奇数行 偶数列 行 < 列 答案是2 否则 答案是0
#include <bits/stdc++.h> using namespace std; int n, m; int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
if ((n & ) == )
{
puts("");
continue;
}
if ((m & ))
{
puts("");
continue;
}
puts(n < m ? "" : "");
}
return ;
}
J - Jumping Choreography
留坑。
K - King of the Waves
题意:给出n个人的胜负关系,打擂台赛,求最后0胜利,给出上场顺序
思路:输出DFS序
#include<bits/stdc++.h> using namespace std; #define N 1010 int n;
int tot = ;
int dep[N];
char mp[N][N];
int ans[N]; inline void DFS(int pos, int cnt)
{
dep[pos] = cnt;
ans[++tot] = pos;
for(int i = ; i <= n; ++i)
{
if(mp[pos][i] == '' && !dep[i])
{
DFS(i, cnt + );
}
}
} int main()
{
while(~scanf("%d", &n))
{
tot = ;
memset(dep, , sizeof dep);
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= n; ++j)
{
scanf(" %c", &mp[i][j]);
}
}
DFS(, );
if(tot != n)
{
puts("impossible");
}
else
{
for(int i = n; i >= ; --i)
{
printf("%d%c", ans[i] - , " \n"[i == ]);
}
}
}
return ;
}
L - Lemonade Trade
题意:给出n个兑换关系,刚开始有1l pink 最后想换到blue 要依次换,可以选择换和不换
思路:O(n) 扫一下,记录在这之前被兑换的颜色饮料最多能被换到多少 然后取max 注意 不能直接乘法,取log 再取e的幂次
#include<bits/stdc++.h> using namespace std; #define N 100010 const int INF = 0x3f3f3f3f;
const double EI = exp(1.0); int cnt;
map<string, int >mp;
double ans[N]; inline void init()
{
mp.clear();
cnt = ;
mp["pink"] = cnt++;
mp["blue"] = cnt++;
ans[] = log(1.0);
ans[] = -INF * 1.0;
} int n;
string a, b;
double w; int main()
{
ios::sync_with_stdio(false);
cin.tie();cout.tie();
while(cin >> n)
{
init();
for(int i = ; i <= n; ++i)
{
cin >> a >> b >> w;
if(mp[a] == )
{
mp[a] = cnt++;
ans[mp[a]] = -INF * 1.0;
}
if(mp[b] == )
{
mp[b] = cnt++;
ans[mp[b]] = -INF * 1.0;
}
int id1 = mp[a], id2 = mp[b];
ans[id1] = max(ans[id1], ans[id2] + log(w));
}
ans[] = pow(EI, ans[]);
ans[] = min(ans[], 10.0);
cout << setiosflags(ios::fixed) << setprecision() << ans[] << endl;
}
return ;
}
M - Manhattan Mornings
题意:给出n个点,起始点和终点,求从起始点到终点的最短路径,最多经过多少点
思路:先排序,固定一个轴,再求最长上升子序列
#include <bits/stdc++.h>
using namespace std; #define N 100010 int n; struct node
{
int x, y;
inline void scan()
{
scanf("%d%d", &x, &y);
}
inline bool operator < (const node &r) const
{
return x < r.x || x == r.x && y < r.y;
}
}point[N], st, ed; int arr[N], brr[N]; inline int DP1(int n)
{
if (n == ) return ;
int i, len, pos;
brr[] = arr[];
len = ;
for (int i = ; i <= n; ++i)
{
if (arr[i] >= brr[len])
{
len = len + ;
brr[len] = arr[i];
}
else
{
int pos = upper_bound(brr + , brr + + len, arr[i]) - brr;
brr[pos] = arr[i];
}
}
return len;
} inline bool cmp (node a, node b)
{
return a.x > b.x || a.x == b.x && a.y < b.y;
} int main()
{
while (scanf("%d", &n) != EOF)
{
st.scan(); ed.scan();
for (int i = ; i <= n; ++i)
point[i].scan();
if (st.x > ed.x) swap(st, ed);
if (st.y < ed.y)
{
sort(point + , point + + n);
int cnt = ;
for (int i = ; i <= n; ++i)
{
if (point[i].x >= st.x && point[i].x <= ed.x && point[i].y >= st.y && point[i].y <= ed.y)
arr[++cnt] = point[i].y;
}
printf("%d\n", DP1(cnt));
}
else
{
sort(point + , point + + n, cmp);
int cnt = ;
for (int i = ; i <= n; ++i)
{
if (point[i].x >= st.x && point[i].x <= ed.x && point[i].y >= ed.y && point[i].y <= st.y)
arr[++cnt] = point[i].y;
}
printf("%d\n", DP1(cnt));
}
}
return ;
}
2017 Benelux Algorithm Programming Contest (BAPC 17) Solution的更多相关文章
- 2014 Benelux Algorithm Programming Contest (BAPC 14)E
题目链接:https://vjudge.net/contest/187496#problem/E E Excellent Engineers You are working for an agency ...
- 2018 Benelux Algorithm Programming Contest (BAPC 18)
目录 Contest Info Solutions A A Prize No One Can Win B Birthday Boy C Cardboard Container D Driver Dis ...
- 2018 Benelux Algorithm Programming Contest (BAPC 18)I In Case of an Invasion, Please. . .
题意:一副无向有权图,每个点有一些人,某些点是避难所(有容量),所有人要去避难所,问最小时间所有人都到达避难所, 题解:dij+二分+最大流check,注意到避难所最多10个,先挨个dij求到避难所的 ...
- Gym -102007 :Benelux Algorithm Programming Contest (BAPC 18) (寒假自训第5场)
A .A Prize No One Can Win 题意:给定N,S,你要从N个数中选最多是数,使得任意两个之和不大于S. 思路:排序,然后贪心的选即可. #include<bits/stdc+ ...
- 2015 Benelux Algorithm Programming Contest (BAPC 15)E - Excellent Engineers
这题想了很久没思路,不知道怎么不sort维护二维的最小值 emmmm原来是线段树/树状数组,一维sort,二维当成下标,维护三维的最小值 #include<bits/stdc++.h> # ...
- Benelux Algorithm Programming Contest 2014 Final(第二场)
B:Button Bashing You recently acquired a new microwave, and noticed that it provides a large number ...
- Benelux Algorithm Programming Contest 2017(D)
传送门:Problem D https://www.cnblogs.com/violet-acmer/p/9677435.html 题意: 研究人员需要使用某种细菌进行实验,给定一个序列代表接下来每个 ...
- 2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019
1.A题 题意:给定第一行的值表示m列的最大值,第m行的值表示n行的最大值,问是否会行列冲突 思路:挺简单的,不过我在一开始理解题意上用了些时间,按我的理解是输入两组数组,找出每组最大数,若相等则输出 ...
- 03.14 ICPC训练联盟周赛,Preliminaries for Benelux Algorithm Programming Contest 2019
A .Architecture 题意:其实就是想让你找到两行数的最大值,然后比较是否相同,如果相同输出'possible',不同则输出'impossible' 思路:直接遍历寻找最大值,然后比较即可 ...
随机推荐
- iOS调用系统相册、相机 显示中文标题
解决手机语言已经设置显示中文 在调用系统相册.相机界面 时显示英文问题, 在 info.plist里面添加Localized resources can be mixed YES 表 ...
- oracle启动报ORA-03113;
[案例] 在重启数据库过程中: SQL> startup ORACLE instance started. Total System Global Area 1.0489E+10 bytes F ...
- iteritems()
iteritems() 是列表的一个方法,用法如下: In [1]: dict1 = {"name": "Jeny", "age": 18, ...
- 使用 XPath
XPath 简介: (1) 前面我们爬取一个网页,都是使用正则表达式来提取想要的信息,但是这种方式比较复杂,一旦有一个地方写错,就匹配不出来了,因此我们可以使用 XPath 来进行提取(2) XPat ...
- 《C++ Primer Plus》第11章 使用类 学习笔记
本章介绍了定义和使用类的许多重要方面.一般来说,访问私有类成员的唯一方法是使用类方法.C++使用友元函数来避开这种限制.要让函数称为友元,需要在类声明中声明该函数,并在声明前加上关键字friend.C ...
- IT公司常见的内网漏洞表格
访问控制类漏洞与隐患 这一类漏洞与隐患属于访问控制与身份鉴别问题,一般有没有配置访问控制.访问控制弱(弱口令或者空口令),身份鉴别可以绕过等问题 漏洞协议组件 漏洞类型 漏洞评级 SSH 弱口令 严重 ...
- python的内存管理与垃圾回收机制学习
一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...
- nodejs 事件EventEmitter
index.js: // 引入 events 模块 var events = require('events'); //处理函数要写在调用前 var eventHandler = function() ...
- java的bean和map互转的工具类
import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;i ...
- 最大网络流(Dinic)
hdu1532 Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...