AT3621

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

纪念\(ATcoder\) 神题\(Orz\)

考虑数位取模,\(*10\)贡献为\(0\)\(+1\)贡献为\(1\)

跑一个同余最短路,在\((\mod K)\)意义下建图,\(i\)\(i+1\)连一条边权为\(1\)的边,\(i\)\(10i\)连一条边权为\(0\)的边,最短路的意义就是产生一个能整除\(K\)的正整数在数位上所需的最小代价

边权只有\(0\)\(1\) \(01BFS\)

注意优先把贡献为\(0\)扔到队头,保证每次从队首取出来的是当前队中距离源点最短的节点

\(O(n+m)\)

struct node{int num,w;};
deque<node>q; int K;
bool v[N];
void bfs(){
	while(!q.empty()){
		node x = q.front(); q.pop_front();
		if(v[x.num]) continue;
		v[x.num] = 1;
		if(!x.num){ printf("%d",x.w); return ; }
		q.push_front((node){x.num*10 % K,x.w});
		q.push_back((node){(x.num+1) % K,x.w + 1});
	}
}
int main(){
	scanf("%d",&K);
	q.push_front((node){1,1});
	bfs();
}
posted @ 2020-10-15 16:54  INFP  阅读(118)  评论(0编辑  收藏  举报