• Small Multiple[ARC084 B]


    【题目描述】
    给定一个整数(k).求一个(k)的整数倍(sum),使得(sum)的数字和最小

    题解

    考试的时候想尽一切办法枚举,卡时 最多卡到70pts

    其实如果把那几个最毒瘤的数放上去完全可以把暴力卡掉

    正解是要建图跑最短路

    考虑(sum)在模(k)意义下的值

    我们建立(k)个节点 编号为(0sim n-1)

    对于每个(i) 连一条(i)((i+1)\% k)的边 边权为(1) 表示(sum+1) 数字和也(+1)

    再连一条(i)((i*10)\% k)的边 边权为(0) 表示(sum*10) 数字和不变

    然后从节点(0)开始 因为第一步肯定走(0)(1)的边(你让(0*10)也没有意义) 所以跑一次节点(1)到节点(0)的最短路即可 到节点(0)(sum)肯定是被(k)整除的 满足题意

    有人可能会问 万一连续走了(10)次第一类边 导致加法进位了怎么办

    由于我们是在图上跑最短路 连续走(10)次第一类边((sum+1+1+1dots +1)) 边权和为(10) 一定是不如走一次第一类边再走一次第二类边(((sum+1)*10)) 到达的是图上的同一个点 但是第二种走法边权和仅为(1) 所以(1)(0)最短路中一定不会有连续走(10)次第一类边的情况

    所以此题的答案就是(0)号节点到(1)号节点的最短路长度+1

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef pair<int, int> pii;
    
    inline int read() {
    	int x = 0, f = 1; char ch = getchar();
    	for (; ch > '9' || ch < '0'; ch = getchar()) if (ch == '-') f = -1;
    	for (; ch <= '9' && ch >= '0'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ '0');
    	return x * f;
    }
    
    int n, ans;
    int head[100005], pre[2000005], to[2000005], val[2000005], sz;
    int dis[100005];
    bool vis[100005];
    
    inline void addedge(int u, int v, int w) {
    	pre[++sz] = head[u]; head[u] = sz; to[sz] = v; val[sz] = w;
    }
    
    priority_queue<pii, vector<pii> , greater<pii> > q;
    
    inline void dijkstra(int st) {
    	memset(dis, 0x3f, sizeof(dis));
    	memset(vis, 0, sizeof(vis));
    	q.push(make_pair(0, st));
    	dis[st] = 1;
    	while (!q.empty()) {
    		int x = q.top().second;
    		q.pop();
    		if (vis[x]) continue;
    		else vis[x] = 1;
    		for (int i = head[x]; i; i = pre[i]) {
    			int y = to[i];
    			if (dis[x] + val[i] < dis[y]) {
    				dis[y] = dis[x] + val[i];
    				q.push(make_pair(dis[y], y));
    			}
    		}
    	}
    }
    
    int main() {
    	n = read();
    	for (int i = 0; i < n; i++) {
    		addedge(i, (i + 1) % n, 1);
    		addedge(i, (i * 10) % n, 0);
    	}
    	dijkstra(1);
    	printf("%d
    ", dis[0]);
    	return 0;
    }
    
  • 相关阅读:
    CSS 选择器之复合选择器
    答辩ppt
    开题报告
    ADS1110/ADS1271
    电感、磁珠和零欧电阻的区别
    ROM、RAM、DRAM、SRAM和FLASH区别
    运放的带宽
    ADC 分辨率和精度的区别
    Verilog
    C语言 文件读取
  • 原文地址:https://www.cnblogs.com/ak-dream/p/AK_DREAM48.html
Copyright © 2020-2023  润新知