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. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  2. CountHunter 6101 最优贸易 强联通缩点

    题目传送门 题解:强连通锁点之后. 就成了一副单向图. 然后对于每个点 找到 后面合法的点的最大值就好了. 合法就是后面的那个点可以走到n号点. 也可以正向跑一遍dij 求出到这个点的最小花费. 然后 ...

  3. 2018年全国多校算法寒假训练营练习比赛(第五场)H Tree Recovery

    Tree Recovery 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %lld 链接:https://w ...

  4. poj 1753 Flip Game(暴力枚举)

    Flip Game   Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 52279   Accepted: 22018 Des ...

  5. CSS3 01. CSS3现状、属性选择器、伪类选择器、结构伪类、伪元素选择器、颜色、文本阴影shadow、盒子模型、私有化前缀

    CSS 3 现状 兼容性差,需添加私有前缀/移动端优于PC端/不断改进中/渐进增强原则/考虑用户群体/遵照产品的方案 : CSS3手册 需要阅读其--阅读及使用指引 []表示全部的可选项 || 或者 ...

  6. spring cloud config使用mysql存储配置文件

    spring cloud config使用mysql存储配置文件 1.结构图 2.pom.xml: <?xml version="1.0" encoding="UT ...

  7. Newtonsoft.Json 序列化

    当我们对一个json数组进行反序列化用Newtonsoft.Json.JsonConvert.DeserializeObject<T>() 通常会报此错误 Newtonsoft.Json. ...

  8. 粗糙版ORM(附详细注释)

    目录 ORM 其他 ORM代码 数据库表代码 mysql代码 db/models.py db/pymysql_opreator.py ORM 作为数据库表记录 和 python中对象的映射关系中间件 ...

  9. .Net基础篇_学习笔记_第七天_三元数表达式(if-else的转换写法)

    三元表达式语法: 表达式1?表达式2:表达式3; 表达式1一般为一个关系表达式.如果表达式1的值为true,那么表达式2的值就是整个三元表达式的值.如果表达式1的值为false,那么表达式3的值就是整 ...

  10. AirFlow常见问题汇总

    airflow常见问题的排查记录如下: 1,airflow怎么批量unpause大量的dag任务 ​ 普通少量任务可以通过命令airflow unpause dag_id命令来启动,或者在web界面点 ...