• Wannafly 挑战赛12 E


    链接:https://www.nowcoder.com/acm/contest/79/E
    来源:牛客网

    题目描述

    小欧在上代数课的时候,老师向大家提出了一个问题,不定方程 ax+by=c 的整数解存在的充要条件是什么。
    聪明的小欧立即举手给出了老师一个完美的回答,放学后,老师叫住小欧给了他一个思考题。
    给出正整数 a 和 b 的值以及两个序列 S 和 V, 求出最小代价的正整数 c 使得不定方程 ax+by=c 有解,且 c 必须满足以下条件:
    1. 组成 c 的数字必须是序列 S 内的。
    2. 每使用序列 S 内的一个数字 Si 就会消耗掉代价 Vi
    3. 序列 S 内的数字使用次数不限。
    4. c 的首位为 u, c的末位为 v。(u,v 也是序列 S 内的) 
    如果有多个代价一样小的答案,只需要 c 的字典序最小的那一个。

    输入描述:

    第一行三个个整数 a,b,n (1 <= a, b <= 100000,  2 <= n <= 10) 
    第二行 n 个整数 S
    i
    (0 <= S
    i
     <= 9) 
    第三行 n 个整数 V
    i
    (1 <= V
    i
    <= 1000) 
    最后一行两个整数 u,v(1 <= u <= 9,  0 <= v <= 9, u != v) 

    输出描述:

    输出一行表示满足条件的 c 。
    如果有多个输出字典序最小的。
    如果不存在输出 -1 。
    示例1

    输入

    10 15 2
    2 0
    1 1
    2 0

    输出

    20
    示例2

    输入

    17 17 4
    0 1 2 7
    1 1 1 1000
    1 0

    输出

    1020

    思路:对于0到1e5的每一个值建一个节点,每个数字对应一条边,u到v有一条数字为x的边当且仅当(u * 10 + x) % gcd(a, b) == v。想到这里,建图完毕直接跑个dij就行了。但是有一个问题,要输出字典序最小路径,正向可能不好记录,
    可以反向建图跑最短路。反向图的起点值是0,连接所有 满足(w * 10 + v) % 10 == 0的w节点即可,但这个0与路径上普通的节点0是不同的,我们要将这个点特殊化一下,可以赋成一个独特的下标10001。最后求10001到u的最短路即可,更新路径
    时根据决策记录上一个节点以及到达此节点的边。
      1 #include <iostream>
      2 #include <fstream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <string>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <stack>
     12 #include <vector>
     13 #include <set>
     14 #include <map>
     15 #include <list>
     16 #include <iomanip>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <bitset>
     20 #include <ctime>
     21 
     22 using namespace std;
     23 
     24 #define pau system("pause")
     25 #define ll long long
     26 #define pli pair<ll, int>
     27 #define pii pair<int, int>
     28 #define pb push_back
     29 #define mp make_pair
     30 #define clr(a, x) memset(a, x, sizeof(a))
     31 
     32 const double pi = acos(-1.0);
     33 const int INF = 0x3f3f3f3f;
     34 const int MOD = 1e9 + 7;
     35 const double EPS = 1e-9;
     36 
     37 /*
     38 #include <ext/pb_ds/assoc_container.hpp>
     39 #include <ext/pb_ds/tree_policy.hpp>
     40 
     41 using namespace __gnu_pbds;
     42 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
     43 */
     44 
     45 int a, b, n, s[15], val[15], u, v, g, cost[15];
     46 int dis[100015];
     47 pii pre[100015];
     48 struct edge {
     49     int v, x;
     50     edge () {}
     51     edge (int v, int x) : v(v), x(x) {}
     52 };
     53 vector<edge> E[100015];
     54 
     55 int gcd(int a, int b) {
     56     return b ? gcd(b, a % b) : a;
     57 }
     58 
     59 void build_graph() {
     60     for (int i = 0; i <= 100000; ++i) {
     61         for (int j = 0; j < 10; ++j) {
     62             if (INF != cost[j]) {
     63                 //E[i].pb(mp((i * 10 + j) % g, cost[j]));
     64                 if ((i * 10 + j) % g == i) continue;
     65                 E[(i * 10 + j) % g].pb(edge(i, j));
     66             }
     67         }
     68     }
     69     for (int i = 0; i <= 100000; ++i) {
     70         if (0 == (i * 10 + v) % g) {
     71             E[100001].pb(edge(i, v));
     72         }
     73     }
     74 }
     75 
     76 int dij() {
     77     clr(dis, INF);
     78     for (int i = 0; i < 100010; ++i) {
     79         pre[i].first = INF;
     80         pre[i].second = INF;
     81     }
     82     priority_queue<pli, vector<pli>, greater<pli> > que;
     83     int s = 100001;
     84     que.push(pli(dis[s] = 0, s));
     85     while (que.size()) {
     86         pli p = que.top(); que.pop();
     87         ll d = p.first;
     88         int x = p.second;
     89         if (dis[x] < d) continue;
     90         for (int i = 0; i < E[x].size(); ++i) {
     91             int y = E[x][i].v, v = E[x][i].x;
     92             /*if (x == y) {
     93                 printf("x = y = %d
    ", x);
     94                 pau;
     95             }*/
     96             int td = d + cost[v];
     97             if (dis[y] < td) continue;
     98             if (td < dis[y]) {
     99                 que.push(pli(dis[y] = td, y));
    100                 pre[y] = mp(x, v);
    101             } else {
    102                 if (v < pre[y].second) pre[y] = mp(x, v);
    103             }
    104         }
    105     }
    106     return dis[u];
    107 }
    108 
    109 int main() {
    110     scanf("%d%d%d", &a, &b, &n);
    111     g = gcd(a, b);
    112     clr(cost, INF);
    113     for (int i = 1; i <= n; ++i) {
    114         scanf("%d", &s[i]);
    115     }
    116     for (int i = 1; i <= n; ++i) {
    117         scanf("%d", &val[i]);
    118         cost[s[i]] = min(cost[s[i]], val[i]);
    119     }
    120     scanf("%d%d", &u, &v);
    121     build_graph();
    122     if (INF == dij()) {
    123         puts("-1");
    124     } else {
    125         printf("%d", u);
    126         int s = u;
    127         while (100001 != s) {
    128             printf("%d", pre[s].second);
    129             s = pre[s].first;
    130         }
    131     }
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    php学习----文件系统
    zabbix添加mysql自定义监控项
    mysql主从库不同步问题
    zabbix分区
    CentOs7.3 安装 MySQL 5.7.21 二进制版本及主从配置
    MySQL数据备份之mysqldump使用
    mysql 占用大量写I/O
    zabbix添加企业微信发送
    Centos7 更新软件及删除多余内核
    zabbix监控vCenter报错
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8672318.html
Copyright © 2020-2023  润新知