【German Collegiate Programming Contest 2018 June 16th】 GCPC 2018 训练题 题解

Problem B: Battle Royale
Battle Royale games are the current trend in video games and Gamers Concealed Punching
Circles (GCPC) is the most popular game of them all. The game takes place in an area that, for
the sake of simplicity, can be thought of as a two-dimensional plane. Movement and positioning
are a substantial part of the gameplay, but getting to a desired location can be dangerous. You
are confident in your ability to handle the other players, however, while you are walking to your
destination, there are two hazards posed by the game itself:
• The game zone is bounded by a blue circle. Outside of this circle, there is a deadly force
field that would instantly take you out of the game.
• Inside the game zone, there is a red circle where you are exposed to artillery strikes. This
circle is also too risky to enter.
You want to move from one spot on the map to another, but the direct path to your destination is
blocked by the red circle, so you need to find a way around it. Can you find the shortest path that
avoids all hazards by never leaving the blue or entering the red circle? Touching the boundaries
of the circles is fine, as long as you do not cross them.
Input
The input consists of:
• one line with two integers xc, yc specifying your current location;
• one line with two integers xd, yd specifying your destination;
• one line with three integers xb, yb, rb specifying the center and radius of the blue circle;
• one line with three integers xr, yr, rr specifying the center and radius of the red circle.
All coordinates have an absolute value of at most 1 000, and 1 ≤ rb, rr ≤ 1 000. The red circle
is strictly inside the blue circle. Your current location and destination are strictly inside the blue
circle and strictly outside of the red circle, and the direct path between them is blocked by the
red circle.
Output
Output the length of the shortest path that does not leave the blue or enter the red circle. The
output must be accurate up to a relative or absolute error (whichever is lower) of 10−7
.
Sample Input 1 Sample Output 1
0 0
10 0
0 0 1000
5 0 2
10.8112187742
GCPC 2018 – Problem B: Battle Royale

题意:两点之间有一个圆形区域不能经过,求两点间最短距离
思路:

分别做两点到圆的切线,加上一段圆弧路径即是最短路。注意精度即可

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
   
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
   
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
   
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
ll n,m;
int main()
{
   
    double  xc,yc,xd,yd,xb,yb,rb,xr,yr,rr;
    cin>>xc>>yc>>xd>>yd>>xb>>yb>>rb>>xr>>yr>>rr;
    double K=(fabs((yd-yc)*xr+(xc-xd)*yr+((xd*yc)-(xc*yd))))/(sqrt(pow(yd-yc,2)+pow(xc-xd,2)));
        double S1=sqrt((xc-xr)*(xc-xr)+(yc-yr)*(yc-yr)),S2=sqrt((xd-xr)*(xd-xr)+(yd-yr)*(yd-yr));
        double L1=sqrt(S1*S1-rr*rr),L2=sqrt(S2*S2-rr*rr);
        double a=acos(K/S1)+acos(K/S2)-acos(rr*1.0/S1)-acos(rr*1.0/S2);
        double ans=L1+L2+a*rr;
        printf("%.10lf",ans);
    return 0;
}

Problem C: Coolest Ski Route
John loves winter. Every skiing season he goes heli-skiing with his friends. To do so, they rent
a helicopter that flies them directly to any mountain in the Alps. From there they follow the
picturesque slopes through the untouched snow.
Of course they want to ski on only the best snow, in the best weather they can get. For this they
use a combined condition measure and for any given day, they rate all the available slopes.
Can you help them find the most awesome route?
Input
The input consists of:
• one line with two integers n (2 ≤ n ≤ 1000) and m (1 ≤ m ≤ 5000), where n is the
number of (1-indexed) connecting points between slopes and m is the number of slopes.
• m lines, each with three integers s, t, c (1 ≤ s, t ≤ n, 1 ≤ c ≤ 100) representing a slope
from point s to point t with condition measure c.
Points without incoming slopes are mountain tops with beautiful scenery, points without outgoing
slopes are valleys. The helicopter can land on every connecting point, so the friends can start
and end their tour at any point they want. All slopes go downhill, so regardless of where they
start, they cannot reach the same point again after taking any of the slopes.
Output
Output a single number n that is the maximum sum of condition measures along a path that the
friends could take.
Sample visualization
Mt. Awesome (1)
Hunter’s Outpost (2)
Stardew Valley (3)
Canopy Vista (4)
Hungry Bear Cave (5)
Riverside Inn (6)
Figure C.1: Map of the second sample case
GCPC 2018 – Problem C: Coolest Ski Route 5
Sample Input 1 Sample Output 1
5 5
1 2 15
2 3 12
1 4 17
4 2 11
5 4 9
40
Sample Input 2 Sample Output 2
6 6
1 2 2
4 5 2
2 3 3
1 3 2
5 6 2
1 2 4
7
GCPC 2018 – Problem C: Coolest Ski Route

题意:求图中最长路径

思路:队友A的,跑一遍dfs即可。

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
   
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
   
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
   
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
int n,m;
int a[10005];
int map1[1005][1005];
bool vis[1005];
int maxx=0;
int in[1005];
int dp[1005];
int DFS(int x)
{
   
    if(vis[x])
    {
   
        maxx=max(dp[x],maxx);
        return dp[x];
    }
    vis[x]=1;
    for(int i=1; i<=n; i++)
    {
   
        if(map1[x][i]!=-1)
            dp[x]=max(dp[x],DFS(i)+map1[x][i]);
    }
    maxx=max(dp[x],maxx);
    return dp[x];
}
int main()
{
   
    n=read();
    m=read();
    memset(map1,-1,sizeof(map1));
    for(int i=0; i<m; i++)
    {
   
        int x,y,z;
        x=read();
        y=read();
        z=read();
        in[y]++;
        if(map1[x][y]==-1||map1[x][y]!=-1&&map1[x][y]<z)
            map1[x][y]=z;
    }
    for(int i=1; i<=n; i++)
        if(!in[i])
            DFS(i);
    cout<<maxx<<'\n';
    return 0;
}

Problem D: Down the Pyramid
Do you like number pyramids? Given a number sequence that represents the base, you are
usually supposed to build the rest of the “pyramid” bottom-up: For each pair of adjacent
numbers, you would compute their sum and write it down above them. For example, given the
base sequence [1, 2, 3], the sequence directly above it would be [3, 5], and the top of the pyramid
would be [8]:
1 2 3
3 5
8
However, I am not interested in completing the pyramid – instead, I would much rather go
underground. Thus, for a sequence of n non-negative integers, I will write down a sequence of
n + 1 non-negative integers below it such that each number in the original sequence is the sum
of the two numbers I put below it. However, there may be several possible sequences or perhaps
even none at all satisfying this condition. So, could you please tell me how many sequences
there are for me to choose from?
Input
The input consists of:
• one line with the integer n (1 ≤ n ≤ 106
), the length of the base sequence.
• one line with n integers a1, . . . , an (0 ≤ ai ≤ 108
for each i), forming the base sequence.
Output
Output a single integer, the number of non-negative integer sequences that would have the input
sequence as the next level in a number pyramid.
Sample Input 1 Sample Output 1
6
12 5 7 7 8 4
2
Sample Input 2 Sample Output 2
3
10 1000 100
0
GCPC 2018 – Problem D: Down the Pyramid

题意:给一个数字三角形的一层,问他的下一层有多少种取法
思路 :简单的规律题。从左到右,更新能选的数的上下界up & down,同时更新答案 = up - down + 1
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值