2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017) Solution
A:Abstract Art
题意:给出n个多边形,求n个多边形分别的面积和,以及面积并
思路:模板
#include <bits/stdc++.h>
using namespace std; #define N 1010
#define mkp make_pair
const double eps = 1e-; inline int sgn(double x)
{
if (fabs(x) < eps) return ;
if (x < ) return -;
return ;
} struct Point
{
double x, y;
inline Point() {}
inline Point(double x, double y) : x(x), y(y) {}
inline void scan() { scanf("%lf%lf", &x, &y); }
inline bool operator == (const Point &b) const { return sgn(x - b.x) == && sgn(y - b.y) == ; }
inline bool operator < (const Point &b) const { return sgn(x - b.x) == ? sgn(y - b.y) < : x < b.x; }
inline Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); }
inline double operator ^ (const Point &b) const { return x * b.y - y * b.x; }
inline double operator * (const Point &b) const { return x * b.x + y * b.y; }
}; inline double seg(Point O, Point A, Point B)
{
if (sgn(B.x - A.x) == ) return (O.y - A.y) / (B.y - A.y);
return (O.x - A.x) / (B.x - A.x);
} struct Polygon
{
int n;
Point p[];
inline void scan(int _n)
{
n = _n;
for (int i = ; i < n; ++i)
p[i].scan();
}
inline double getarea()
{
double sum = ;
for (int i = ; i < n; ++i)
sum += (p[i] ^ p[(i + ) % n]);
return fabs(sum) / ;
}
}poly[N]; int n;
pair <double, int> s[N]; inline double Polyunion(int n)
{
double res = ;
for (int i = ; i <= n; ++i)
{
int sz = poly[i].n;
for (int j = ; j < sz; ++j)
{
int m = ;
s[m++] = mkp(, );
s[m++] = mkp(, );
Point a = poly[i].p[j], b = poly[i].p[(j + ) % sz];
for (int k = ; k <= n; ++k)
{
if (i != k)
{
int sz2 = poly[k].n;
for (int ii = ; ii < sz2; ++ii)
{
Point c = poly[k].p[ii], d = poly[k].p[(ii + ) % sz2];
int c1 = sgn((b - a) ^ (c - a));
int c2 = sgn((b - a) ^ (d - a));
if (c1 == && c2 == )
{
if (sgn((b - a) * (d - c)))
{
s[m++] = mkp(seg(c, a, b), );
s[m++] = mkp(seg(c, a, b), -);
}
}
else
{
double s1 = (d - c) ^ (a - c);
double s2 = (d - c) ^ (b - c);
if (c1 >= && c2 < ) s[m++] = mkp(s1 / (s1 - s2), );
else if (c1 < && c2 >= ) s[m++] = mkp(s1 / (s1 - s2), -);
}
}
}
}
sort(s, s + m);
double pre = min(max(s[].first, 0.0), 1.0), now, sum = ;
int cov = s[].second;
for (int j = ; j < m; ++j)
{
now = min(max(s[j].first, 0.0), 1.0);
if (!cov) sum += now - pre;
cov += s[j].second;
pre = now;
}
res += (a ^ b) * sum;
}
}
return fabs(res) / ;
} inline void Run()
{
while (scanf("%d", &n) != EOF)
{
double tot = ;
for (int i = , m; i <= n; ++i)
{
scanf("%d", &m);
poly[i].scan(m);
tot += poly[i].getarea();
}
printf("%.10f %.10f\n", tot, Polyunion(n));
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
B:Craters
题意:给出若干个圆,求一个最小的围栏使得将所有圆围住,并且围栏离每个圆的边界至少有10个单位长度
思路:因为半径最多5000 先将半径+10,再将圆5000等分(也不一定5000, 足够大就可以),然后求凸包
#include <bits/stdc++.h>
using namespace std; #define N 2000010
#define mkp make_pair
const double eps = 1e-;
const double PI = acos(-1.0); inline int sgn(double x)
{
if (fabs(x) < eps) return ;
if (x < ) return -;
return ;
} struct Point
{
double x, y;
inline Point() {}
inline Point(double x, double y) : x(x), y(y) {}
inline void scan() { scanf("%lf%lf", &x, &y); }
inline bool operator == (const Point &b) const { return sgn(x - b.x) == && sgn(y - b.y) == ; }
inline bool operator < (const Point &b) const { return sgn(x - b.x) == ? sgn(y - b.y) < : x < b.x; }
inline Point operator - (const Point &b) const { return Point(x - b.x, y - b.y); }
inline double operator ^ (const Point &b) const { return x * b.y - y * b.x; }
inline double operator * (const Point &b) const { return x * b.x + y * b.y; }
inline double distance(const Point &b) const { return hypot(x - b.x, y - b.y); }
}; struct Polygon
{
int n;
Point p[N];
inline void push(Point p0) { p[n++] = p0; }
struct cmp
{
Point p;
cmp(const Point &p0) { p = p0; }
inline bool operator () (const Point &aa, const Point &bb)
{
Point a = aa, b = bb;
int d = sgn((a - p) ^ (b - p));
if (d == )
return sgn(a.distance(p) - b.distance(p)) < ;
return d > ;
}
};
inline void norm()
{
Point mi = p[];
for (int i = ; i < n; ++i) mi = min(mi, p[i]);
sort(p, p + n, cmp(mi));
}
inline void getconvex(Polygon &convex)
{
sort(p, p + n);
convex.n = n;
for (int i = ; i < min(n, ); ++i)
convex.p[i] = p[i];
if (convex.n == && (convex.p[] == convex.p[])) --convex.n;
if (n <= ) return;
int &top = convex.n;
top = ;
for (int i = ; i < n; ++i)
{
while (top && sgn((convex.p[top] - p[i]) ^ (convex.p[top - ] - p[i])) <= ) --top;
convex.p[++top] = p[i];
}
int temp = top;
convex.p[++top] = p[n - ];
for (int i = n - ; i >= ; --i)
{
while (top != temp && sgn((convex.p[top] - p[i]) ^ (convex.p[top - ] - p[i])) <= )
--top;
convex.p[++top] = p[i];
}
if (convex.n == && (convex.p[] == convex.p[])) --convex.n;
convex.norm();
}
inline double getarea()
{
double sum = ;
for (int i = ; i < n; ++i)
sum += (p[i] ^ p[(i + ) % n]);
return fabs(sum) / ;
}
inline double getcircumference()
{
double sum = ;
for (int i = ; i < n; ++i)
sum += p[i].distance(p[(i + ) % n]);
return sum;
}
}poly, ans; int n; inline void Run()
{
while (scanf("%d", &n) != EOF)
{
double x, y, r; poly.n = ;
for (int i = ; i <= n; ++i)
{
scanf("%lf%lf%lf", &x, &y, &r); r += ;
double angle = ;
for (int j = ; j <= ; ++j, angle += PI / )
poly.push(Point(x + r * cos(angle), y + r * sin(angle)));
}
poly.getconvex(ans);
printf("%.10f\n", ans.getcircumference());
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
C:DRM Messages
水。
#include <bits/stdc++.h> using namespace std; #define N 15010 char str[N]; int main()
{
while(~scanf("%s",str))
{
int len = strlen(str);
int tmp = ;
int l = len / ;
for(int i = ; i < l; ++i)
{
tmp = (tmp + (str[i] - 'A')) % ;
}
for(int i = ; i < l; ++i)
{
str[i] = str[i] + tmp;
while(str[i] > 'Z')
{
str[i] -= ;
}
}
tmp = ;
for(int i = l; i < len; ++i)
{
tmp = (tmp + (str[i] - 'A')) % ;
}
for(int i = l; i < len; ++i)
{
str[i] = str[i] + tmp;
while(str[i] > 'Z')
{
str[i] -= ;
}
}
for(int i = ; i < l; ++i)
{
str[i] = str[i] + str[i + l] - 'A';
while(str[i] > 'Z')
{
str[i] -= ;
}
}
for(int i = ; i < l; ++i)
{
putchar(str[i]);
}
printf("\n");
}
return ;
}
D - Game of Throwns
用栈维护。水。
#include<bits/stdc++.h> using namespace std; int n, m;
string s;
stack<int>st; inline int change(string s)
{
int i = (s[] == '-');
int flag = (s[] == '-');
int num = ;
for(int len = s.length();i < len; ++i)
{
num = num * + (s[i] - '');
}
if(flag)
{
num = -num;
}
return num;
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
while(cin >> n >> m)
{
while(!st.empty()) st.pop();
for(int i = ; i < m; ++i)
{
cin >> s;
if(s == "undo")
{
int num;
cin >> num;
for(int j = ; j < num; ++j)
{
if(!st.empty()) st.pop();
}
}
else
{
int num = change(s);
st.push(num);
}
}
int tmp = ;
while(!st.empty())
{
int num = st.top();
tmp += num;
st.pop();
}
tmp = (tmp % n + n) % n;
cout << tmp << endl;
}
return ;
}
E - Is-A? Has-A? Who Knowz-A?
题意:有两种关系,一种是 is-a 一种是 has-a 给出n对关系,然后有m次询问,回答询问的关系是否存在
思路:
如果 A is-a B B is-a C 那么 A is-a C
如果 A is-a B B has-a C 那么 A has-a C
假设is-a关系为0 has-a 关系为1
如果A 和 B 的关系为0 那么 A 和 B 后面所有的关系 都是 B 和其的关系
如果A 和 B 的关系为1,那么A 和 B 后面所有的关系都是1
然后对于每一个点,BFS预处理出它和其他点的关系
#include<bits/stdc++.h> using namespace std; #define N 510 int link[N][N][]; struct node{
int pos;
int flag;
inline node(){}
inline node(int pos, int flag) :pos(pos), flag(flag){};
}; string s1, s2, s3;
map<string,int>mp;
int cnt;
int n, m;
vector<node>vec[N]; inline void init()
{
memset(link, , sizeof link);
for(int i = ; i < N; ++i) vec[i].clear();
mp.clear();
cnt = ;
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
while(cin >> n >> m)
{
init();
for(int i = ; i <= n; ++i)
{
cin >> s1 >> s2 >> s3;
if(mp[s1] == ) mp[s1] = cnt++;
if(mp[s3] == ) mp[s3] = cnt++;
int id1 = mp[s1];
int id2 = mp[s3];
int f = ;
if(s2[] == 'h') f = ;
vec[id1].push_back(node(id2, f));
}
for(int i = ; i < cnt; ++i)
{
link[i][i][] = ;
queue<node>q;
q.push(node(i, ));
while(!q.empty())
{
node st = q.front();
q.pop();
for(auto it : vec[st.pos])
{
if(link[i][it.pos][st.flag | it.flag]) continue;
link[i][it.pos][st.flag | it.flag] = ;
q.push(node(it.pos, it.flag | st.flag));
}
}
}
for(int cas = ; cas <= m; ++cas)
{
cin >> s1 >> s2 >> s3;
int id1 = mp[s1];
int id2 = mp[s3];
int f = ;
if(s2[] == 'h') f = ;
cout << "Query " << cas << ": " << (link[id1][id2][f] ? "true" : "false") << endl;
}
}
return ;
}
F - Keeping On Track
题意:给出n + 1 个点,n 条边,就是一棵树,然后求去除一个点,使得破坏的关系最多,并且挽留的关系最多
思路:DFS下去,然后对每一个点统计一下如果去除这个点,答案是多少,维护一下
#include <bits/stdc++.h> using namespace std; #define N 100010
#define ll long long struct Edge
{
int to, nx;
inline Edge() {}
inline Edge(int to, int nx) : to(to), nx(nx) {}
}edge[N << ]; int n;
int head[N], pos;
ll cnt[N];
ll ans, remind; inline void Init()
{
memset(head, -, sizeof head);
memset(cnt, , sizeof cnt);
pos = ; ans = ; remind = ;
} inline void addedge(int u, int v)
{
edge[++pos] = Edge(v, head[u]); head[u] = pos;
edge[++pos] = Edge(u, head[v]); head[v] = pos;
} inline void DFS(int u, int pre)
{
cnt[u] = ;
vector <ll> vv;
for (int it = head[u]; ~it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == pre) continue;
DFS(v, u);
cnt[u] += cnt[v];
vv.push_back(cnt[v]);
}
vv.push_back(n + - cnt[u]);
sort(vv.begin(), vv.end());
ll tmp = ;
for (int i = , len = vv.size(); i < len; ++i)
{
tmp += vv[i] * (n - vv[i]);
}
tmp /= ;
if(tmp > ans)
{
ans = tmp;
int len = vv.size();
if(len > )
remind = vv[len - ] * vv[len - ];
}
else if(tmp == ans)
{
int len = vv.size();
if(len > )
remind = max(remind, vv[len - ] * vv[len - ]);
}
} int main()
{
while (scanf("%d", &n) != EOF)
{
Init();
for (int i = , u, v; i <= n; ++i)
{
scanf("%d%d", &u, &v);
addedge(u, v);
}
DFS(, -);
printf("%lld %lld\n", ans, ans - remind);
}
return ;
}
G - A Question of Ingestion
题意:给定初始的胃口,和每天有的食物。如果第一天吃了东西,那么第二天的胃口下降到2/3 如果一天没吃,那么胃口恢复为3/2
如果连续两天都没吃,那么恢复为原来的
思路:有两种状态,吃或者不吃,记忆化搜索
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define N 110 int dp[N][N][N]; int arr[N];
int brr[N];
int n, m; inline int DFS(int cnt, int eat, int no)
{
if(cnt > n) return ;
if(eat < ) eat = ;
if(dp[cnt][eat][no] != -) return dp[cnt][eat][no];
//eat
int ans1 = min(brr[eat], arr[cnt]) + DFS(cnt + , eat + , );
//not eat
int ans2;
if(no)
{
ans2 = DFS(cnt + , , );
}
else
{
ans2 = DFS(cnt + , eat - , );
}
dp[cnt][eat][no] = max(ans1, ans2);
return dp[cnt][eat][no];
} int main()
{
while(~scanf("%d %d", &n, &m))
{
memset(dp, -, sizeof dp);
for(int i = ; i <= n; ++i)
{
scanf("%d", &arr[i]);
}
brr[] = m;
for(int i = ; i < N; ++i) brr[i] = brr[i - ] * / ;
int ans = DFS(, , );
printf("%d\n", ans);
}
return ;
}
H - Sheba's Amoebas
题意:找连通块,八个方向
思路:DFS
#include<bits/stdc++.h> using namespace std; #define N 110 int dir[][] = {,,
,,
-,,
,-,
,,
,-,
-,-,
-,
}; int n, m;
char mp[N][N]; inline bool judge(int x,int y)
{
if(x < || x > n || y < || y > m || mp[x][y] == '.') return false;
else return true;
} inline void DFS(int x,int y)
{
mp[x][y] = '.';
for(int i = ; i < ; ++i)
{
int dx = x + dir[i][];
int dy = y + dir[i][];
if(judge(dx, dy))
{
DFS(dx, dy);
}
}
} int main()
{
while(~scanf("%d %d",&n ,&m))
{
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= m; ++j)
{
scanf(" %c",&mp[i][j]);
}
}
int ans = ;
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= m; ++j)
{
if(mp[i][j] == '#')
{
ans++;
DFS(i, j);
}
}
}
printf("%d\n",ans);
}
return ;
}
I - Twenty Four, Again
留坑。
J - Workout for a Dumbbell
题意:有十个机器,Jim要在十个机器上工作三轮,对于每一个机器都有一个固定的工作时间以及工作之后需要的休息时间,然后每个机器还有另外一个工人要跟Jim抢机器,如果Jim要使用某一天机器的时候,刚好有工人要用或者在用,那么只能等工人用完Jim再用,求Jim工作三轮后需要的时间
思路:模拟一下,每次更新另外一个工人的起始时间,就可以判断当Jim要去用的时候,那个工人是在工作还是在休息了
#include<bits/stdc++.h> using namespace std; #define N 100 const int n = ; typedef long long ll; ll W[N], R[N], C[N], w[N], r[N], c[N], t[N]; int main()
{
for(int i = ; i <= n; ++i)
{
scanf("%lld %lld", W + i, R + i);
C[i] = W[i] + R[i];
}
for(int i = ; i <= n; ++i)
{
scanf("%lld %lld %lld",w + i, r + i, t + i);
c[i] = w[i] + r[i];
}
ll ans = ;
for(int cnt = ; cnt <= ; ++cnt)
{
for(int i = ; i <= n; ++i)
{
if(ans < t[i])
{
ans += C[i];
t[i] = max(t[i], ans - R[i]);
}
else
{
int tmp = (ans - t[i]) / c[i];
t[i] += tmp * c[i] + w[i];
if(ans < t[i]) ans = t[i];
ans += C[i];
t[i] = max(t[i] + r[i], ans - R[i]);
}
}
}
printf("%lld\n", ans - R[n]);
return ;
}
2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017) Solution的更多相关文章
- Gym-101673 :East Central North America Regional Contest (ECNA 2017)(寒假自训第8场)
A .Abstract Art 题意:求多个多边形的面积并. 思路:模板题. #include<bits/stdc++.h> using namespace std; typedef lo ...
- 2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016) F 区间dp
Problem F Removal GameBobby Roberts is totally bored in his algorithms class, so he’s developed a li ...
- 2014-2015 ACM-ICPC East Central North America Regional Contest (ECNA 2014) A、Continued Fractions 【模拟连分数】
任意门:http://codeforces.com/gym/100641/attachments Con + tin/(ued + Frac/tions) Time Limit: 3000/1000 ...
- [bfs,深度记录] East Central North America Regional Contest 2016 (ECNA 2016) D Lost in Translation
Problem D Lost in Translation The word is out that you’ve just finished writing a book entitled How ...
- MPI Maelstrom(East Central North America 1996)(poj1502)
MPI Maelstrom 总时间限制: 1000ms 内存限制: 65536kB 描述 BIT has recently taken delivery of their new supercom ...
- ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbilisi, November 24, 2010
ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbil ...
- poj 2732 Countdown(East Central North America 2005)
题意:建一个家庭树,找出有第d代子孙的名字,按照要求的第d代子孙的数从大到小输出三个人名,如果有一样大小子孙数的,就按字母序从小到大将同等大小的都输出,如果小于三个人的就全输出. 题目链接:http: ...
- East Central North America Region 2015
E 每过一秒,当前点会把它的值传递给所有相邻点,问t时刻该图的值 #include <iostream> #include <cstdio> #include <algo ...
- POJ 1240 Pre-Post-erous! && East Central North America 2002 (由前序后序遍历序列推出M叉树的种类)
题目链接 问题描述 : We are all familiar with pre-order, in-order and post-order traversals of binary trees. ...
随机推荐
- Linux环境PHP5.5以上连接SqlServer2008
linux版本:64位CentOS 6.4 Nginx版本:nginx1.8.0 php版本:php5.5.28 Sqlserver版本:2008 FreeTDS版本:0.95 关于Linux环境安装 ...
- 【RF库Collections测试】combine lists
Arguments: [ *lists ]Combines the given `lists` together and returns the result. The given lists are ...
- jquery 添加可操作,编辑不可操作
--jsp <td class="queryTitle" width="100">优惠券批次号</td> <td class=&q ...
- IOS视频播放器的制作
利用自带MPMoviePlayerController来实现视频播放,首先要在项目中导入MediaPlayer.Framework框架包. 在视图控制器中 #import "MediaPla ...
- JZOJ.5287【NOIP2017模拟8.16】最短路
Description
- 小程序开通微信支付 --- 微信商户平台绑定微信小程序APPID
首先情况是这样的:现有公司有个公众号,已经开通了微信支付(已经有一个商户平台),现在需要开发 微信小程序(也有微信支付),如果在小程序里面重新申请 微信支付,就显得比较麻烦.腾讯官方已经提供了 一个商 ...
- 几何+点与线段的位置关系+二分(POJ2318)
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10666 Accepted: 5128 Description ...
- 了解MIP(Mobile Instant Pages)
mip官网:https://www.mipengine.org/ 什么是mip? mip是百度在2016年提出的移动网页加速器项目.可以简单理解为是一个规范. mip能做什么? mip能帮助站 ...
- Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载地址
MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...
- WebConfig配置详解大全
<?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...