zoukankan      html  css  js  c++  java
  • [ARC084B] Small Multiple 解题报告

    给定一个整数 (K) ,求一个 (K) 的整数倍 (SUM) ,使得 (SUM) 的数位累加和最小。

    选拔考的最后一题,我还以为是什么数学+贪心。。。

    出来老师说是最短路,震撼了我一会。

    感觉这个模型也挺妙的,可以只考虑所有数字对于 (K) 的模数,然后按照各位数字之和来转移。

    对于数字 (x) ,转移有两种:

    • 转移到 (x+1) ,各位数字之和 (+1)

    • 转移到 (10x) ,各位数字之和不变。

    然后可以以模数为点,储存模数为 (x) 的数字的各位数字之和的最小值,然后跑最短路。

    可以发现第一种情况不一定是合法的,因为可能会进位,但是如果从 (1) 开始跑最短路,存在进位就要经过至少 (9)(+1) 操作,可以证明这一定不是最短路。

    然后这题就变成一道最短路问题了。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int M=1e5+5;
    
    int read(){
    	int x=0,y=1;char ch=getchar();
    	while(ch<'0'||ch>'9') y=(ch=='-')?-1:1,ch=getchar();
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x*y;
    }
    
    int n,tot=0,first[M];
    struct Edge{ int nxt,to,w; }e[M*10];
    void add(int x,int y,int z){
    	e[++tot]=(Edge){first[x],y,z};
    	first[x]=tot;
    }
    
    struct Dian{
    	int id,val;
    	bool operator <(const Dian &x) const{ return x.val<val; }
    };
    priority_queue<Dian> q;int dis[M];bool inq[M];
    void DIJ(){
    	for(int i=0;i<n;i++) dis[i]=1e9,inq[i]=0;
    	q.push((Dian){1,0});dis[1]=0;
    	while(!q.empty()){
    		int u=q.top().id;q.pop();
    		if(inq[u]) continue ;inq[u]=1;
    		for(int i=first[u];i;i=e[i].nxt){
    			int v=e[i].to,w=e[i].w;
    			if(dis[v]>dis[u]+w){
    				dis[v]=dis[u]+w;
    				if(!inq[v]) q.push((Dian){v,dis[v]});
    			}
    		}
    	}
    }
    
    void solve(){
    	n=read();
    	for(int i=1;i<n;i++) for(int j=0;j<9;j++) add(i,(i*10+j)%n,j);
    	DIJ();
    	printf("%d
    ",dis[0]+1);
    }
    
    int main(){
    	solve();
    }
    
  • 相关阅读:
    configure: error: no acceptable cc found in $PATH
    SQL server的错误日志导致服务器C盘满
    域名/IP 正则表达式
    rpm 基本命令
    VB TO C#
    yum 的基本操作
    在服务器上怎么检查一个网站的在线连接数有多大。
    MSSQL2005不能连接远程有非法字符密码的数据库
    按账目类型和日期查看账目
    梦断代码读书笔记(二)
  • 原文地址:https://www.cnblogs.com/wzp-blog/p/13547804.html
Copyright © 2011-2022 走看看