1. Elevator (Gym-241680 E)

题意: 一个高度为 hhh 的电梯,初始位置在第一层。电梯有四个按钮。

  1. 向上移动 aaa 格
  2. 向上移动 bbb 格
  3. 向上移动 ccc 格
  4. 返回第一层

问 1~h1~h1~h 层中有多少层是可达的。(1≤h≤1018,1≤a,b,c≤100000)(1\leq h\leq 10^{18},1\leq a,b,c\leq 100000)(1≤h≤1018,1≤a,b,c≤100000)

思路: 观察数据范围可以发现,a、b、ca、b、ca、b、c 数据范围比较小,可以从此处着手。

不难发现,如果 222 可以达到,则 2+a2+a2+a、2+2∗a2+2*a2+2∗a、2+3∗a2+3*a2+3∗a… 均可到达。即我们以 aaa 作为基底,如果 x(x&lt;a)x\ (x&lt;a)x (x<a) 可以到达,则 y(y%a=x)y\ (y\%a=x)y (y%a=x) 也可到达。

因此问题转化为对于 x(x&lt;a)x(x&lt;a)x(x<a) 来说,最小的可达的 yyy 是多少?(y%a=x)(y\%a=x)(y%a=x) 既然问题变成了求最小,那么不难想到使用最短路来解决这个问题。

我们枚举 x(0≤x&lt;a)x\ (0\leq x&lt;a)x (0≤x<a),令 xxx 与 (x+b)%a(x+b)\%a(x+b)%a 和 (x+c)%a(x+c)\%a(x+c)%a 连边,边权分别为 bbb、ccc。然后起点为 111,即可求出到达所有 xxx 时的最小值。

求取答案时就可以枚举 xxx,然后求 dis[x]~hdis[x]~hdis[x]~h 中有多少个 moda=xmod\ a=xmod a=x 的值即可。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e6+100;
const ll inf = 1e15;
const db EPS = 1e-9;
using namespace std;ll h,a,b,c,dis[N];
int head[N],tot,vis[N];
struct Node{int to,next;ll w;
}e[M];void init() {tot = 1;}void add(int x, int y, ll w){e[++tot].to = y, e[tot].next = head[x], head[x] = tot, e[tot].w = w;
}void dijkstra(int s){priority_queue<pair<ll,int> > q;while(q.size()) q.pop();rep(i,0,a-1) dis[i] = inf, vis[i] = 0;dis[s%a] = 1;q.push(make_pair(-dis[s%a],s%a)); while(q.size()){int x = q.top().second; q.pop();if(vis[x]) continue;vis[x] = 1;for(int i = head[x]; i; i = e[i].next){int y = e[i].to;if(dis[y] > dis[x] + e[i].w){dis[y] = dis[x] + e[i].w;q.push(make_pair(-dis[y],y));}}}
}int main()
{freopen("elevator.in","r",stdin);freopen("elevator.out","w",stdout);scanf("%lld%lld%lld%lld",&h,&a,&b,&c);init();rep(i,0,a-1){add(i,(i+b)%a,b);add(i,(i+c)%a,c);}dijkstra(1);ll ans = 0;rep(i,0,a-1){if(dis[i] == inf || dis[i] > h) continue;ans += 1ll + (h-dis[i])/a;}printf("%lld\n",ans);return 0;
}
2. Sums (Gym-100753 M)

题意: nnn 个数,kkk 组询问。每组询问给出一个 bbb,问能否用这 nnn 个数组成 bbb。(1≤ai≤5000,1≤bi≤109)(1\leq a_i\leq 5000,1\leq b_i\leq 10^9)(1≤ai​≤5000,1≤bi​≤109)

思路: n2n^2n2 建图,直接跑最短路得到答案即可。

代码:

//以a为循环,求出 0~a-1 中每一个数字第一次被到达的数字
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const ll inf = 1e15;
const db EPS = 1e-9;
using namespace std;ll dis[N];
int n,a[N],vis[N],k;void dijkstra(int s){priority_queue<pair<ll,int> > q;while(q.size()) q.pop();rep(i,0,a[1]-1) dis[i] = inf, vis[i] = 0;dis[0] = 0;q.push(make_pair(0,0)); while(q.size()){int x = q.top().second; q.pop();if(vis[x]) continue;vis[x] = 1;rep(i,2,n){int y = (x+a[i])%a[1];if(dis[y] > dis[x] + a[i]){dis[y] = dis[x] + a[i];q.push(make_pair(-dis[y],y));}}}
}int main()
{scanf("%d",&n);rep(i,1,n) scanf("%d",&a[i]);dijkstra(0);scanf("%d",&k);rep(i,1,k){int tp,hp; scanf("%d",&tp);hp = tp%a[1];if(tp >= dis[hp]) printf("TAK\n");else printf("NIE\n");}return 0;
}
3. 墨墨的等式 (Bzoj-2118)

题意: 对于 a1∗x1+a2∗x2+...+an∗xn=Ba_1*x_1+a_2*x_2+...+a_n*x_n=Ba1​∗x1​+a2​∗x2​+...+an​∗xn​=B 是否存在非负整数解。给出 n、ain、a_in、ai​ 以及 BBB 的范围,求出有多少个 BBB 使等式存在非负整数解。(1≤N≤12,0≤ai≤5∗105,1≤BMin≤BMax≤1012)(1\leq N\leq 12,0\leq a_i\leq 5*10^5,1\leq BMin\leq BMax\leq 10^{12})(1≤N≤12,0≤ai​≤5∗105,1≤BMin≤BMax≤1012)

思路: 与上面题目做法一致,选取最小的 aaa 作为基底,然后 n2n^2n2 建图,求出第一次到达 0~a−10~a-10~a−1 中各数字的最小值,然后统计答案即可。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 20+100;
const int M = 12*5*1e5+100;
const db EPS = 1e-9;
using namespace std;int n,head[M],tot,vis[M];
ll l,r,a[N],ans,dis[M];
struct Edge{int to,next,w;
}e[M];void add(int x,int y,int z){e[++tot].to = y, e[tot].next = head[x], head[x] = tot, e[tot].w = z;
}priority_queue< pair<ll,int> > q;void dijkstra(int s){while(q.size()) q.pop();memset(dis,0x3f,sizeof dis);dis[s] = 0; //第一次到达%a[1] == 0的点为0q.push(make_pair(0,s));while(q.size()){int x = q.top().second;q.pop();if(vis[x]) continue;vis[x] = 1;for(int i = head[x]; i; i = e[i].next){int y = e[i].to, z = e[i].w;if(dis[y] > dis[x]+z){dis[y] = dis[x]+z;q.push(make_pair(-dis[y],y));}}}}int main()
{scanf("%d%lld%lld",&n,&l,&r);int ctt = 0;rep(i,1,n){ll tpp; scanf("%lld",&tpp);if(tpp != 0) a[++ctt] = tpp;} n = ctt;if(n == 0) printf("0\n");else{rep(i,1,n)if(a[1] > a[i]) swap(a[1],a[i]); //找到最小的,降低复杂度rep(i,0,a[1]-1){rep(j,2,n){add(i,(i+a[j])%a[1],a[j]);}}dijkstra(0);rep(i,0,a[1]-1){ll tp1 = 0, tp2 = 0;if(l-1-dis[i] >= 0)tp1 = (l-1-dis[i])/a[1]+1;if(r-dis[i] >= 0)tp2 = (r-dis[i])/a[1]+1;ans += tp2-tp1;}printf("%lld\n",ans);}return 0;
}

最短路应用 —— 解决某些计数、数论问题相关推荐

  1. 数据库导出到excel解决科学计数法问题

    用Navicat等工具导出数据到excel的时候,身份证等超过11位的数字会自动转换成科学计数法,末尾数字变成"0000".如何解决? 解决方式:给超过11位的数字末尾添加   \ ...

  2. java科学计数法问题_java 解决科学计数法问题

    问题:当java从excel获取数据后,会出现科学计数法,比如0.0004变成4.0E-4,5000变成5E+3问题. 解决:1:当是5E+3问题 这个很好解决: 1).判断是否是科学计数法 Stri ...

  3. 用JavaScript实现列数据的标出重复项和去重(解决科学计数法的excel数据去重异常问题)

    是这样,通常情况下标出重复项和去重复项这种比较简单的工作交给excel就可以了,但是excel有时候会出现无法处理的情况,比如说一串数字太长,会自动用科学计数法来表示,这个时候如果标出重复项就会出现乱 ...

  4. AcWing 851. spfa求最短路(解决负边权最短路)

    题目链接 https://www.acwing.com/problem/content/853/ 思路 就是SPFA求最短路的模板,其思路大概是我们要更新所有能被松弛的边,然后更新松弛的边的边,然后就 ...

  5. 对象是否要被回收(引用计数和可达性分析算法)

    java堆和方法区主要存放各种类型的对象(方法区中也存储一些静态变量和全局常量等信息),那么我们在使用GC对其进行回收的时候首先要考虑的就是如何判断一个对象是否应该被回收.也就是要判断一个对象是否还有 ...

  6. POJ 3463 Sightseeing(次短路问题)

    题意: 给定一张有向图,求最短路的条数,如果次短路长度 = 最短路 + 1,则输出最短路和次短路条数的和. 思路: 1. 一开始想到 POJ 2449 求 k 短路的方法求解,case 都过的差不多了 ...

  7. dijkstra算法matlab程序_编程习题课 | 用最短路算法为你的小地图导航

    简介:路网拓扑的正确导入方式,运筹学算法的完整实战案例,最详细的代码讲解与分享. 引言:在研究路径选择和流量分配等交通问题时,常常会用到最短路算法.用最短路算法解决交通问题存在两个难点:一.算法的选择 ...

  8. php 大数运算类,PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法

    本文实例讲述了PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法.分享给大家供大家参考,具体如下: PHP计算大数值运算时会出错,当数字太大时,数值会变成科学计数.那怎么来进行PHP超大数值 ...

  9. 人群计数(Crowd Counting)研究综述

    52CV曾经报道过两篇关于人群计数的新出论文(可在精华文章汇总中找到),皆获得不少关注,今天的文章来自复旦大学计算机的在读博士老田和电闪雷鸣为我们介绍人群计数的相关技术和进展,想对此方向有更全面把握的 ...

  10. 微博计数:从关系服务到访问计数, Redis 持续优化支撑万亿级访问(含 PPT)

    关注"数据和云",精彩不容错过 编者按:本文由刘东辉向高可用架构供稿,基于在 Redis 用户交流会上的演讲内容整理.这是一篇历史文章,但是仍然可以帮助我们理解 Redis 的应用 ...

最新文章

  1. 基于C++的PyTorch模型部署
  2. 一文解读“边缘计算” 和物联网的亲密关系!
  3. layui table行点击tr_layui框架table表格实现单击行选中checkbox功能
  4. python xpath语法-【python】爬虫: lxml解析库、XPath语法详解
  5. 【MATLAB】基本绘图 ( 图形设置 | 坐标轴开关 | box 开关 | 网格开关 | 坐标轴样式 )
  6. JAVA——HttpClient封装工具类
  7. JavaScript入门(part6)--运算符
  8. 【QQ输入法】QQ输入法-剪切板 释放内存
  9. c# 使用NOPI 操作Excel
  10. 程序员的自我修养(收藏)
  11. 基于搜狗新闻语料库的词向量模型训练(Windows下)
  12. Android很好看的登陆界面(包含详细代码)
  13. 步步为营Hibernate全攻略(二)剪不断理还乱之:一对多关联映射
  14. 内存分析(二) AVFrame
  15. 网站优化入门SEO图文五大步骤
  16. SNMP Trap的session问题
  17. 【动手学深度学习】06-ResNet解析
  18. 创客学院 level1第二节学习完成
  19. 2017-11-11 今天的工作任务
  20. 正身以俟时,守己而律物

热门文章

  1. 关键字AUTO_INCREMENT 重命名表 修改列的属性。
  2. 交换机路由器常用命令
  3. ASP.NET2.0下使用AJAX调用Webservice的方法
  4. 将两个数组河滨_【探索】苏州河两岸将新增12公顷公园绿地,四季皆有景
  5. wordpress让百度分享支持https
  6. Android自动播放下一曲,环信Android自动播放下一条语音
  7. mysql 8.0安装_MySQL5.7升级到8.0过程详解
  8. html compiler注册机,XXX计算器1.8注册分析和注册机代码
  9. java awt 教程_JAVA教程第五讲AWT图形用户界面设计
  10. 安装activex手机控件_86/BRZ 免“油饼”安装 Defi 机油压力表