A Amsterdam Distance

题意

求圆环上的两点距离。

分析

显然是沿半径方向走到内圈再走圆弧最短。

代码

#include <bits/stdc++.h>
using namespace std;
double m,n,r,sx,sy,tx,ty;
const double pi=acos(-1.0);
int main(){
scanf("%lf%lf%lf%lf%lf%lf%lf",&m,&n,&r,&sx,&sy,&tx,&ty);
double ans=fabs(ty-sy)*r/n;
double mr=min(sy,ty)*r/n;
double ps=fabs(tx-sx);
ans+=ps*pi*mr/m;
printf("%.14lf\n",min(ans,(ty+sy)*r/n));
return 0;
}

C Collatz Conjecture

题意

n个数,求所有不同区间的gcd值的不同个数。

分析

  • 序列的gcd问题经常就是暴力乱搞...不过姿势要对,因为gcd降得很快。
  • 考虑暴力,我们从长度为1的区间依次合并,即每次a[i]=gcd(a[i],a[i+1]);,然后直接对a数组去重,比如6 4 2 2,此时两个长度为3的区间的gcd值都是2,所以直接去重舍弃第二个,因为整个序列从头开始的gcd值一定是不增的,所以直接舍弃掉后面小的是正确的。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+50;
int n;
ll a[N];
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
set<ll> s;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
s.insert(a[i]);
}
for(int r=n;r>1;r--){
for(int i=1;i<r;i++){
a[i]=gcd(a[i],a[i+1]);
s.insert(a[i]);
}
r=unique(a+1,a+r)-a;
}
printf("%d\n",int(s.size()));
return 0;
}

D Detour

题意

给一个图,对每个节点不能走该节点到终点最短路方向的边,求路径。

分析

从终点跑一遍最短路,相当于多源到终点的最短路,然后删除最短路边(单向边),再从起点跑一遍最短路。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+50;
const int M=2e6+50;
struct Edge{
int u,v;
ll w;
int next,vis;
}e[M*2];
int cnt,head[N];
void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,ll w){
e[cnt]=Edge{u,v,w,head[u],0};
head[u]=cnt++;
e[cnt]=Edge{v,u,w,head[v],0};
head[v]=cnt++;
}
int s,t,n,m,u,v,p[N];
ll w;
int vis[N];
ll dis[N];
const ll INF=1e18;
struct node{
int v;
ll w;
bool operator<(const node& rhs)const{
return w>rhs.w;
}
};
void dijk(bool del){
for(int i=1;i<=n;i++){
vis[i]=0;
dis[i]=INF;
p[i]=-1;
}
dis[s]=0;
priority_queue<node> q;
q.push(node{s,0});
while(!q.empty()){
node t=q.top();
q.pop();
int u=t.v;
if(vis[u]){
continue;
}
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
ll w=e[i].w;
if(del && e[i].vis){
continue;
}
if(!vis[v] && dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
p[v]=u;
q.push(node{v,dis[v]});
}
}
}
}
int ans[N];
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++){
scanf("%d%d%lld",&u,&v,&w);
u++;
v++;
add(u,v,w);
}
s=2,t=1;
dijk(0);
// for(int u=1;u<=n;u++){
// for(int i=head[u];i!=-1;i=e[i].next){
// int v=e[i].v;
// if(p[u]==v){
// e[i].vis=1;
// }
// }
// }
for(int i=0;i<cnt;i++){
int u=e[i].u;
int v=e[i].v;
ll w=e[i].w;
//printf("%d %d %lld %lld\n",u,v,abs(dis[u]-dis[v]),w);
if(dis[u]-dis[v]==w){
e[i].vis=1;
//printf("%d %d\n",u,v);
}
}
s=1,t=2;
dijk(1);
if(dis[t]==INF){
printf("impossible\n");
}else{
int tot=0;
for(int i=t;i!=-1;i=p[i]){
ans[tot++]=i-1;
}
printf("%d",tot);
for(int i=tot-1;i>=0;i--){
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}

E Easter Eggs

题意

有b个蓝色点和r个红色点,将n个物品分配到这两种点上,使得红色点上的物品和蓝色点上的物品的最小距离最大。

分析

  • 最小距离最大,考虑二分答案,即二分最小距离,转化为使得两种点的任意两点的距离都大于mid。
  • 两种点考虑二分图,对点之间距离小于mid的建边,那我们要求的就是该二分图的最大点独立集,即两两之间没有边,也就是距离大于mid。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1005;
int n,b,r;
int vis[N],mt[N];
int g[N][N];
ll x[N],y[N],cost[N][N];
bool dfs(int u,int n){
for(int i=1;i<=n;i++){
if(!vis[i] && g[u][i]){
vis[i]=1;
if(mt[i]==-1 || dfs(mt[i],n)){
mt[i]=u;
return true;
}
}
}
return false;
}
int solve(){
int ans=0;
memset(mt,-1,sizeof(mt));
for(int i=1;i<=b;i++){
memset(vis,0,sizeof(vis));
ans+=dfs(i,r);
}
return ans;
}
bool check(ll dis){
memset(g,0,sizeof(g));
for(int i=1;i<=b;i++){
for(int j=1;j<=r;j++){
if(cost[i][j]<dis){
g[i][j]=1;
}
}
}
int sol=solve();
return b+r-sol>=n;
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&b,&r);
for(int i=1;i<=b+r;i++){
scanf("%lld%lld",&x[i],&y[i]);
}
for(int i=1;i<=b;i++){
for(int j=1;j<=r;j++){
cost[i][j]=1ll*(x[i]-x[b+j])*(x[i]-x[b+j])+1ll*(y[i]-y[b+j])*(y[i]-y[b+j]);
}
}
ll L=0,R=1e18+50;
ll ans=0;
while(L<=R){
ll mid=(L+R)/2;
if(check(mid)){
L=mid+1;
ans=mid;
}else{
R=mid-1;
}
}
printf("%.10lf\n",sqrt(ans*1.0));
return 0;
}

F Falling Apart

题意

n个数,两人轮流取,两个人都要最大。

分析

排序。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=20;
int a[N],n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
int aa=0,bb=0;
int f=0;
for(int i=n;i>=1;i--){
if(f){
bb+=a[i];
}else{
aa+=a[i];
}
f^=1;
}
printf("%d %d\n",aa,bb);
return 0;
}

I Irrational Division

题意

有一个p*q的黑白相间的格子图,你站在左边往右切,另一个人站在下边往上切,切到的部分黑色加1分,白色减1分,两人都按最优策略尽量让自己分最大,问最大可能的分数差值绝对值。

分析

  • 显然分奇偶判断一下。
  • 当p为偶数,列无论怎么取都是黑白相同0,所以最优取法是保守取剩下偶数列,这样对方也只能保守取偶数行,最后答案为0。如果取剩下奇数列,那最后的得分是0和-2,虽然答案变大,但是并不是最优的使得两人得分尽量多的策略。
  • 当p为奇数,q也为奇数时,第一步保守取偶数列得分0,剩下奇数列,对方显然可以只选一行,得1分,最后结果是0和1,若第一步激进选奇数列得1分,考虑直接取完的情况,所以最后结果是1和0,所以答案为1。
  • 当p为奇数,q为偶数时,还需要判断p和q的关系。
  • 当p<q时,第一步保守取偶数列得0分,对方最优肯定也是保守取1行,转化为pq均为偶数的情况,答案为0,第一步激进取1列得1分,对方只能保守取偶数行得0分,我们再保守取,最后肯定能剩下一个白色角落给对方,因此最后结果是0和-2,答案为2。
  • 当p>q时,第一步保守取偶数列得0分,对方最优肯定取奇数行剩下偶数行,转化为pq均为偶数的情况,答案为0,第一步激进取1列得1分,对方最优取偶数行剩下奇数行,我们只能保守取偶数列,最后肯定剩下一个白色角落给我们,因此最后结果是0和0,答案为0。

代码

#include <bits/stdc++.h>
using namespace std;
int p,q;
int main(){
scanf("%d%d",&p,&q);
if(p%2==0 && q%2==0){
printf("0\n");
}else if(p%2==0 && q%2==1){
printf("0\n");
}else if(p%2==1 && q%2==0){
if(p<q){
printf("2\n");
}else{
printf("0\n");
}
}else if(p%2==1 && q%2==1){
printf("1\n");
}
return 0;
}

K King of the Waves

题意

给n个人的对战胜负关系,要求构造一个擂台挑战顺序使得0号赢。

分析

  • 从0号开始按照胜负关系递归下去,如果能访问到每个点,那就可以,按dfs序输出即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+50;
char s[N][N];
int w[N][N],vis[N];
int n,cnt;
vector<int> ans;
void dfs(int u){
cnt++;
vis[u]=1;
for(int i=0;i<n;i++){
if(vis[i] || w[u][i]!=1){
continue;
}
dfs(i);
}
ans.push_back(u);
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",s[i]);
for(int j=0;j<n;j++){
if(s[i][j]=='X'){
w[i][j]=-1;
}else{
w[i][j]=s[i][j]-'0';
}
}
}
dfs(0);
if(cnt==n){
for(int i=0;i<n;i++){
printf("%d%c",ans[i],i==n-1?'\n':' ');
}
}else{
printf("impossible\n");
}
return 0;
}

L Lemonade Trade

题意

初始有1升pink,给n个交易关系,问最后最多能换多少blue。

分析

  • 一开始看错题意以为可以随便交易,那就是建图跑。
  • 由于只能按顺序交易,那么直接把字符串映射一下然后简单dp即可,注意把乘法改成加log,然后最后判断大于10也不能先计算结果再判断,因为2的1e5次方太大,所以直接用log判断。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+50;
const double INF=1e18;
map<string,int> idx;
int n;
char a[15],b[15];
double w;
double mx[N];
int vis[N];
int main(){
//freopen("in.txt","r",stdin);
int tot=0;
scanf("%d",&n);
idx["pink"]=++tot;
vis[tot]=1;
for(int i=1;i<N;i++){
mx[i]=-INF;
}
mx[1]=0.0;
for(int i=1;i<=n;i++){
scanf("%s%s%lf",a,b,&w);
if(idx.find(a)==idx.end()){
idx[a]=++tot;
}
if(idx.find(b)==idx.end()){
idx[b]=++tot;
}
if(vis[idx[b]]){
mx[idx[a]]=max(mx[idx[a]],mx[idx[b]]+log2(w));
vis[idx[a]]=1;
}
}
int t=idx["blue"];
if(vis[t]){
if(mx[t]>log2(10.0)){
printf("10.000000000\n");
}else{
printf("%.14lf\n",min(10.000000000,pow(2.0,mx[idx["blue"]])));
}
}else{
printf("0.0000000000\n");
}
return 0;
}

M Manhattan Mornings

题意

给定起点终点,求二维的最长不下降子序列。

分析

  • 一维排序,按顺序枚举,然后另一位离散化后在起点终点范围内的点加入线段树中,并查询最大值更新。
  • 注意起点终点的四种可能位置。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+50;
struct Orz{
vector<int> a;
void clr(){
a.clear();
}
int siz(){
return a.size();
}
void add(int x){
a.push_back(x);
}
void work(){
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
}
int idx(int x){
return lower_bound(a.begin(),a.end(),x)-a.begin()+1;
}
int val(int i){
return a[i-1];
}
}orz;
struct ST{
#define ls i<<1
#define rs i<<1|1
#define mid (l+r)/2
int mx[N*4];
void pushup(int i){
mx[i]=max(mx[ls],mx[rs]);
}
void build(int i,int l,int r){
mx[i]=0;
if(l==r){
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
}
void update(int i,int l,int r,int p,int v){
if(l==r && l==p){
mx[i]=max(mx[i],v);
return;
}
if(p<=mid){
update(ls,l,mid,p,v);
}else{
update(rs,mid+1,r,p,v);
}
pushup(i);
}
int query(int i,int l,int r,int ql,int qr){
if(ql<=l && qr>=r){
return mx[i];
}
int ans=0;
if(ql<=mid){
ans=max(ans,query(ls,l,mid,ql,qr));
}
if(qr>mid){
ans=max(ans,query(rs,mid+1,r,ql,qr));
}
return ans;
}
}ac;
struct node{
int x,y,w;
}a[N];
bool cmp1(node a,node b){
if(a.y!=b.y){
return a.y<b.y;
}else{
return a.x<b.x;
}
}
bool cmp2(node a,node b){
if(a.y!=b.y){
return a.y<b.y;
}else{
return a.x>b.x;
}
}
int n,sx,sy,tx,ty,nx[N],ny[N];
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&n);
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
orz.clr();
orz.add(sx);
orz.add(sy);
orz.add(tx);
orz.add(ty);
for(int i=1;i<=n;i++){
scanf("%d%d",&nx[i],&ny[i]);
orz.add(nx[i]);
orz.add(ny[i]);
}
orz.work();
int ns=orz.siz();
sx=orz.idx(sx);
sy=orz.idx(sy);
tx=orz.idx(tx);
ty=orz.idx(ty);
if(sy>ty){
swap(sx,tx);
swap(sy,ty);
}
a[0]=node{sx,sy};
a[1]=node{tx,ty};
for(int i=1;i<=n;i++){
nx[i]=orz.idx(nx[i]);
ny[i]=orz.idx(ny[i]);
a[i+1]=node{nx[i],ny[i]};
}
if(sx<tx){
sort(a,a+n+2,cmp1);
for(int i=0;i<=n+1;i++){
if(a[i].x>=sx && a[i].x<=tx && a[i].y>=sy && a[i].y<=ty){
int x=a[i].x;
int t=ac.query(1,1,ns,1,x);
a[i].w=t+1;
ac.update(1,1,ns,x,a[i].w);
}
}
printf("%d\n",ac.query(1,1,ns,sx,tx)-2);
}else{
sort(a,a+n+2,cmp2);
for(int i=0;i<=n+1;i++){
if(a[i].x>=tx && a[i].x<=sx && a[i].y>=sy && a[i].y<=ty){
int x=a[i].x;
int t=ac.query(1,1,ns,x,ns);
a[i].w=t+1;
ac.update(1,1,ns,x,a[i].w);
}
}
printf("%d\n",ac.query(1,1,ns,tx,sx)-2);
}
return 0;
}

gym101666题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. Spring Boot 2.0 教程 | 快速集成整合消息中间件 Kafka

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...

  2. 上海学生事务中心&新华路派出所的位置

    上海学生事务中心: 地址:冠生园路401号    工作时间:9:00-17:00    电话:021-64829191 新华路派出所: 地址:新华路590弄21号    工作时间:周一至周六 9:00 ...

  3. webpack4.0 babel配置遇到的问题

    babel配置 babel版本升级到8.x之后发现出现了很多问题.首先需要安装 "@babel/core": "^7.1.2", "@babel/pl ...

  4. 关闭Linux(Ubuntu)错误报告

    关于错误报告 网上查了下,Ubuntu(包括elementary,elementary是基于Ubuntu的)桌面版预装了Apport,它是一个错误收集系统,会收集软件崩溃.未处理异常和其他,包括程序b ...

  5. js 大量数据优化,通用方法

    当页面渲染太多标签时,会出现卡顿的,典型就是类似table数据太多时,非常卡顿.如果选择分页,没必要讨论,这儿只讨论采用滚动的情况.解决思路很简单,就是页面不展示出来的元素,从页面上删除掉,最难点在于 ...

  6. Erlang模块gen_fsm翻译

    模块摘要     通用有限状态机行为.   描述     用于实现有限状态机的行为模块.使用该模块实现的通用有限状态机进程(gen_fsm)将具有一组标准的接口函数,并包括用于跟踪和错误报告的功能.它 ...

  7. 阿里云机器维护-gitlab Forbidden

    gitlab这台机子运行了一两年了,今天突然拉代码不能拉了,看了下接口403 登录网页 Forbidden 看了下是前两天挖矿病毒引发的,大致因为大量请求导致ip被封了 我们只要把这台机子加入配置白名 ...

  8. 为什么说 Java 程序员必须掌握 Spring Boot ?(转)

    Spring Boot 2.0 的推出又激起了一阵学习 Spring Boot 热,那么, Spring Boot 诞生的背景是什么?Spring 企业又是基于什么样的考虑创建 Spring Boot ...

  9. 为git创建远程仓库

    首先生成ssh公钥: 将公钥添加到git: 测试秘钥是否通过: 然后就可以到web界面看到标注的地方被绿了: 但是我的没有绿,不知道为啥,难道没有女朋友的原因吗? rm -rf .ssh 重来好几遍都 ...

  10. JVM参数配置及详解 -Xms -Xmx -Xmn -Xss 调优总结

    堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制.32位系统 下,一般限制在1.5G~2G;64为操 ...