B .Battle Royale

题意:给你两个点A,B,以及一个圆S,保证两个点在圆外,且其连线与圆相交,求两点间最短距离。

思路:显然是要分别与圆相切,然后在圆弧想走,直到相交。 那么ans=与圆相交的直线距离+圆弧上的距离; 前者不难求。 后者的话有些抽象,因为不知道怎么取固定角度,但是如果想到atan2了就不难了,因为atan2求出的角度是固定了标准的,注意对用两个atan2求出来的角度求其夹角时,注意不要错过2pi;同时取min(angle,2*pi-angle)。  还不懂的,看代码。

(camp也有类似的题

#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1.0);
double ans;
double dist(double x1,double y1,double x2,double y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
pair<double,double> angle(double x1,double y1,double x,double y,double r)
{
double d=dist(x1,y1,x,y);
ans+=(sqrt(d*d-r*r));
double ang1=atan2(y1-y,x1-x);
double ang2=acos(r/d);
return make_pair(ang1+ang2,ang1-ang2); //返回圆心与切点的角度
}
double getlen(double A,double B,double r){
A=fabs(A-B); if(A>=pi*) A-=pi*;
return r*min(A,pi*-A);
}
int main()
{
double x1,y1,x2,y2,x,y,r;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
scanf("%lf%lf%lf",&x,&y,&r);
scanf("%lf%lf%lf",&x,&y,&r);
pair<double,double> A=angle(x1,y1,x,y,r);
pair<double,double> B=angle(x2,y2,x,y,r);
double Cirlen=getlen(A.first,B.first,r);
Cirlen=min(Cirlen,getlen(A.first,B.second,r));
Cirlen=min(Cirlen,getlen(A.second,B.first,r));
Cirlen=min(Cirlen,getlen(A.second,B.second,r));
printf("%.10lf\n",ans+Cirlen);
return ;
}

E .Expired License

题意:给定你两个最多带5位小数的double型a,b,让你用用一对素数x y表示他们的比值。

思路:我们把a和b都乘1e5,化简验证是否是素数即可。 但是要注意精度误差,我们可以给把数加一个1e-7之后再乘1e5.

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
using namespace std;
const int maxn=;
const double eps=1e-;
int p[maxn],cnt; bool vis[maxn];
void prime()
{
vis[]=;
rep(i,,maxn-){
if(!vis[i]) p[++cnt]=i;
rep(j,,cnt){
if(p[j]*i>=maxn) break;
vis[i*p[j]]=;
if(!(i%p[j])) break;
}
}
}
int main()
{
double A,B; int C,D,T;
scanf("%d",&T); prime();
while(T--){
scanf("%lf%lf",&A,&B);
C=(int)((A+eps)*); D=(int)((B+eps)*);
int g=__gcd(C,D);
C/=g; D/=g;
if(!vis[C]&&!vis[D]) printf("%d %d\n",C,D);
else if(C==&&D==) puts("2 2");
else puts("impossible");
}
return ;
}

H .Hyper Illuminati

题意:给定一个数N(<1e16),问是否存在n和s,满足1^n+2^n+3^n+...s^n=N;输出n+1,s;

思路:如果2<=n<=53,我们发现s不会太大,我们可以把所有的都求出来;如果n>53,则有s<=2,我们可以把s=2的值都求出来。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
using namespace std;
int main()
{
ll ans=,N;
cin>>N; //N=M;
rep(i,,){ //幂位i+1
ans=;
rep(j,1LL,N){
ll tmp=;
rep(k,,i){
if(tmp>N/j) {tmp=N+; break;}
tmp*=j;
}
if(tmp>N) break;
ans+=tmp;
if(ans==N) return printf("%lld %lld\n",i+,j),;
if(ans>=N) break;
}
}
rep(i,,){ //长度位2
ll tmp=;
rep(j,1LL,N){
tmp*=;
if(j>=){
if(tmp+==N) return printf("%lld %lld\n",j+,),;
}
if(tmp+>=N) break;
}
}
puts("impossible");
return ;
}

D .Down the Pyramid

题意:金字塔的每一层的位置的值=下一层的两个值之和,现在给你最倒数第二层的值a1,a2...an,问你最后一层有多少种情况,满足所哟数不小于0。

思路:我们假设第一个位置位b0=x,那么b1=a1-x; b2=a2-b1=a2-a1+x.. 中间给限制让所有数大于等于0,则有x<=a1; x>=a1-a2; x<=a3+a2-a1 ; x>=...。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
ll a[maxn],sum,Mn,Mx;
int main()
{
int N; scanf("%d",&N);
rep(i,,N) scanf("%lld",&a[i]);
Mn=; Mx=a[];
rep(i,,N){
sum=a[i]-sum;
if(i&) Mx=min(Mx,sum);
else Mn=max(Mn,-sum);
}
if(Mx<Mn) puts("");
else printf("%lld\n",Mx-Mn+);
return ;
}

C .Coolest Ski Route

题意:给定带边权有向图,让你找一个最长的链,满足买个点最多遍历一次。

思路:记忆化搜索即可。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
using namespace std;
const int maxn=;
int dis[maxn],Laxt[maxn],Next[maxn],To[maxn],Len[maxn],cnt;
void add(int u,int v,int L){
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=L;
}
int dfs(int u){
if(dis[u]!=-) return dis[u]; dis[u]=;
for(int i=Laxt[u];i;i=Next[i]) dis[u]=max(dis[u],dfs(To[i])+Len[i]);
return dis[u];
}
int main()
{
int N,M,u,v,l,ans=;
scanf("%d%d",&N,&M);
rep(i,,N) dis[i]=-;
rep(i,,M){
scanf("%d%d%d",&u,&v,&l);
add(u,v,l);
}
rep(i,,N) ans=max(ans,dfs(i));
printf("%d\n",ans);
return ;
}

F .Fighting Monsters

题意:给定N个怪兽,问是否能选处两个怪兽,使得他们相互攻击,最后活着的怪兽剩1滴血。

思路:即是问是否寻在相邻的Fibonacci数。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int F[maxn+],a[maxn+],Laxt[maxn+];
int main()
{
int N,tot=;
F[]=; F[]=;
for(int i=;;i++){
F[i]=F[i-]+F[i-];
if(F[i]>maxn){ tot= i; break;}
}
scanf("%d",&N);
rep(i,,N) scanf("%d",&a[i]),Laxt[a[i]]=i;
rep(i,,N) {
if(a[i]==&&Laxt[]>i) return printf("%d %d\n",i,Laxt[]),;
}
rep(i,,tot-) {
if(Laxt[F[i]]&&Laxt[F[i+]]) return printf("%d %d\n",Laxt[F[i]],Laxt[F[i+]]),;
}
puts("impossible");
return ;
}

I .It's Time for a Montage

by 罗

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=;
const int maxn=1e3+;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int h[maxn];
int v[maxn];
int isok(int x,int n){
for(int i=;i<=n;i++){
if(h[i]-v[i]+x==)continue;
else if(h[i]-v[i]+x>)return true;
else return false;
}
return true;
}
int main()
{
int n;
cin>>n;
for(int i=;i<=n;i++)cin>>h[i];
for(int i=;i<=n;i++)cin>>v[i];
int ans=;
for(int i=;i<=;i++){
if(isok(i,n)){
cout<<i<<endl;
return ;
}
}
return ;
}

L. Logic Puzzle

题意:就是扫雷,让你复原雷图。

思路:从左上到右下,关系是唯一对应的。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int a[maxn][maxn],vis[maxn][maxn];
int x[]={,,,-,-,-,,,};
int y[]={,-,,,-,,,-,};
int main()
{
int N,M; scanf("%d%d",&N,&M);
rep(i,,N+) rep(j,,M+) scanf("%d",&a[i][j]);
rep(i,,N)
rep(j,,M){
if(a[i][j]==){
vis[i+][j+]=;
rep(k,,) {
if(i++x[k]>=&&i++x[k]<=N+&&j++y[k]>=&&j++y[k]<=M+)
a[i++x[k]][j++y[k]]--;
}
}
else vis[i+][j+]=-;
}
rep(i,,N+) rep(j,,M+) {
if(a[i][j]!=) { return puts("impossible"),;}
}
rep(i,,N){
rep(j,,M) putchar(vis[i][j]==?'X':'.');
puts("");
}
return ;
}

K .Kitchen Cable Chaos

题意:...

思路:就是让你选几个棍子,使得(长度和+K-10)/个数不超过5,而且最大,背包即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,w,v) for(int i=w;i>=v;i--)
using namespace std;
const int maxn=;
int dp[maxn][],a[maxn];
int main() {
int N,g;
scanf("%d%d",&N,&g);
rep(i,,N) scanf("%d",&a[i]);
dp[][]=;
rep(i,,N)
rep2(j,N,)
rep2(k,maxn-,a[i])
dp[k][j]|=dp[k-a[i]][j-];
double ans=-1.0;
rep(k,g-,maxn-){
rep(j,,N){
if(!dp[k][j]) continue;
double tmp=(k+-g)*1.0/(j+1.0);
if(tmp<=5.0) ans=max(ans,tmp);
}
}
if(ans<0.0) puts("impossible");
else printf("%.8f\n", ans);
return ;
}
/*
3 70 20 35 50
*/

M .Mountaineers

题意:给定N*M座山,Q次询问,让你最小化从山S到山T经过的山的最高高度。

思路:不难想到排序,然后启发式合并。 每次合并两个连通块,并且看有没有询问的S和T分别再两个连通块里。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int h[maxn],Laxt[maxn],Next[maxn],To[maxn],id[maxn];
int cnt,ans[maxn],fa[maxn],N,M,Q,vis[maxn],sz[maxn];
pair<int,int>p[maxn];
set<int>s[maxn]; set<int>::iterator it;
int get(int x,int y){ return (x-)*M+y; }
void add(int u,int v,int op)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; id[cnt]=op;
}
int find(int x){ return fa[x]; }
void merge(int u,int v,int H)
{
if(sz[u]<sz[v]) swap(u,v);
for(it=s[v].begin();it!=s[v].end();it++){
int x=*it;
for(int i=Laxt[x],f=-;i;i=Next[i]) {
if(!ans[id[i]]&&s[u].find(To[i])!=s[u].end()) {
ans[id[i]]=H; }
if(ans[id[i]]){
if(f==-) Laxt[x]=Next[i];
else Next[f]=Next[i];
}
f=i;
}
}
for(it=s[v].begin();it!=s[v].end();it++){
s[u].insert(*it); fa[*it]=u;
}
s[v].clear();
sz[u]+=sz[v];
}
int main()
{
scanf("%d%d%d",&N,&M,&Q);
rep(i,,N) rep(j,,M){
cnt++; fa[cnt]=cnt; scanf("%d",&h[cnt]);
p[cnt].first=h[cnt],p[cnt].second=cnt;
s[cnt].insert(cnt); sz[cnt]=;
}
cnt=; int x1,y1,x2,y2;
rep(i,,Q){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1==x2&&y1==y2) ans[i]=h[get(x1,y2)];
x1=get(x1,y1); x2=get(x2,y2);
add(x1,x2,i); add(x2,x1,i);
}
sort(p+,p+N*M+);
rep(i,,N*M){
int pos=p[i].second,H=p[i].first;
vis[p[i].second]=;
if(pos%M!=&&vis[pos-]){
int fu=find(pos),fv=find(pos-);
if(fu!=fv) merge(fu,fv,H);
}
if(pos>M&&vis[pos-M]){
int fu=find(pos),fv=find(pos-M);
if(fu!=fv) merge(fu,fv,H);
}
if(pos<=N*M-M&&vis[pos+M]){
int fu=find(pos),fv=find(pos+M);
if(fu!=fv) merge(fu,fv,H);
}
if(pos%M!=&&vis[pos+]){
int fu=find(pos),fv=find(pos+);
if(fu!=fv) merge(fu,fv,H);
}
}
rep(i,,Q) printf("%d\n",ans[i]);
return ;
}

更美妙的方法:依然是建立连通关系,不过我们是建立一棵树,从小到大连通,每次把之前的连通块的根作为当前点的儿子。 最后就可以在线询问了,询问S和T的答案是LCA的点的值。 感觉有点向ST表求LCA的原理。 深度越低,最大值越大,我们我们需要求LCA。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int fa[maxn],cnt,ans[maxn],vis[][],rt;
int f[maxn][],dep[maxn]; vector<int>G[maxn];
struct in{
int x,y,id,h;
in(){}
in(int xx,int yy,int ii,int hh):x(xx),y(yy),id(ii),h(hh){}
friend bool operator <(in w,in v){ return w.h<v.h; }
}s[maxn];
void add(int u,int v){ G[u].push_back(v); }
int find(int x){
if(x==fa[x]) return x; return fa[x]=find(fa[x]);
}
void dfs(int u,int pre){
f[u][]=pre; dep[u]=dep[pre]+;
for(int i=;i<G[u].size();i++) dfs(G[u][i],u);
}
int LCA(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
for(int i=;i>=;i--) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
if(u==v) return u;
for(int i=;i>=;i--) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
return f[u][];
}
int main()
{
int N,M,Q,h,x1,x2,y1,y2;
scanf("%d%d%d",&N,&M,&Q);
rep(i,,N)
rep(j,,M){
scanf("%d",&h); cnt++; fa[cnt]=cnt;
ans[cnt]=h; s[cnt]=in(i,j,cnt,h);
}
sort(s+,s+cnt+);
rep(i,,cnt){
x1=s[i].x; y1=s[i].y;
if(vis[x1-][y1]&&x1!=&&find(s[i].id)!=find(s[i].id-M))
add(fa[s[i].id],find(s[i].id-M)),fa[find(s[i].id-M)]=fa[s[i].id];
if(vis[x1+][y1]&&x1!=N&&find(s[i].id)!=find(s[i].id+M))
add(fa[s[i].id],find(s[i].id+M)),fa[find(s[i].id+M)]=fa[s[i].id];
if(vis[x1][y1-]&&y1!=&&find(s[i].id)!=find(s[i].id-))
add(fa[s[i].id],find(s[i].id-)),fa[find(s[i].id-)]=fa[s[i].id];
if(vis[x1][y1+]&&y1!=M&&find(s[i].id)!=find(s[i].id+))
add(fa[s[i].id],find(s[i].id+)),fa[find(s[i].id+)]=fa[s[i].id];
vis[s[i].x][s[i].y]=;
}
rt=find();
dfs(rt,);
rep(i,,)
rep(j,,cnt) f[j][i]=f[f[j][i-]][i-];
rep(i,,Q){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1=(x1-)*M+y1; x2=(x2-)*M+y2;
int Lca=LCA(x1,x2);
printf("%d\n",ans[Lca]);
}
return ;
}

Gym .102021 .German Collegiate Programming Contest (GCPC 18) (寒假gym自训第三场)的更多相关文章

  1. (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

    layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...

  2. 2018 German Collegiate Programming Contest (GCPC 18)

    2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...

  3. Gym .101933 Nordic Collegiate Programming Contest (NCPC 2018) (寒假gym自训第四场)

    (本套题算是比较温和吧,就是罚时有点高. B .Baby Bites 题意:给出一个婴儿给出的数组,有一些数字听不清楚,让你还原,问它是否是一个从1开始的一次增加的数组. 思路:从左往右依次固定,看是 ...

  4. (寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

    layout: post title: (寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) au ...

  5. 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)(9/11)

    $$2017-2018\ ACM-ICPC\ German\ Collegiate\ Programming\ Contest (GCPC 2017)$$ \(A.Drawing\ Borders\) ...

  6. 2015 German Collegiate Programming Contest (GCPC 15) + POI 10-T3(12/13)

    $$2015\ German\ Collegiate\ Programming\ Contest\ (GCPC 15) + POI 10-T3$$ \(A.\ Journey\ to\ Greece\ ...

  7. 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

    A Drawing Borders 很多构造方法,下图可能是最简单的了 代码: #include<bits/stdc++.h> using namespace std; ; struct ...

  8. 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Solution

    A. Drawing Borders Unsolved. B. Buildings Unsolved. C. Joyride Upsolved. 题意: 在游乐园中,有n个游玩设施,有些设施之间有道路 ...

  9. German Collegiate Programming Contest 2018​ B. Battle Royale

    Battle Royale games are the current trend in video games and Gamers Concealed Punching Circles (GCPC ...

随机推荐

  1. InnoDB支持的最大事务数量

    Innodb存储引擎有rollback segment,每个rollback segment中记录了1024个undo log segment,在每个undo log segment中进行undo页的 ...

  2. hive top n

    hive 中窗口函数row_number,rank,dense_ran,ntile分析函数的用法 hive中一般取top n时,row_number(),rank,dense_ran()这三个函数就派 ...

  3. Utf-8+Bom编码导致的读取数据部分异常问题

    项目中经常会有这种场景,在配置文件中配置对应关系,项目启动的时候从中读取数据存入map缓存起来,这样使用的时候就可以直接从map找到对应的映射关系. 然后遇到了这么一个诡异的问题,一个简单的映射关系如 ...

  4. web前端开发面试题(答案)

    1.xhtml和html有什么区别? HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同:XHTML 元素必须被正确地嵌套.XHTML 元素必须被关闭.标签名必须 ...

  5. unity中UI的屏幕自适应代码

    public void ScreenUISelfAdptation(Transform scaleUI) { float widthrate = UnityEngine.Screen.width / ...

  6. js中 offset /client /scroll总结

    offset家族(只能读取,不能操作): offsetLeft:元素的边框的外边缘距离与已定位的父容器(offsetparent)的左边距离(就是子元素左边框到父元素左边框的距离). offsetTo ...

  7. day4-python基础-运算符

    本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算术运算符 ...

  8. delphi 演示数据路径

    链接里默认的--------------------------- Error --------------------------- I/O error for file "C:\Prog ...

  9. 解决了好几个软件的构建问题,在解决部署问题,bluemix部署

    https://www.puteulanus.com/archives/838#comment-961新版 Bluemix 一键搭建 SS 脚本 https://blog.feixueacg.com/ ...

  10. Asp.Net WebApi核心对象解析(一)

    生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...