b_51_01組成的N的倍數(同餘定理+bfs)
阿新 • • 發佈:2020-10-26
給定一個自然數N,找出一個M,使得M>0且M是N的倍數,並且M的10進製表示只包含0或1。求最小的M。
例如:N=4,M=100。(1<=N<=10^6)
思路:M只能有0/1,所以可以從1開始bfs,每次將隊頭的數×10+0/1可列舉到所有合法數字,但時耗很長,且會溢位,不可取
優化:M%N為0(M>0),則證明M是N的倍數,那我可以直接開一個結構體(string,int)記錄M以及M%N的餘數,用檢查餘數結果是否0來判斷當前string M是否是N的倍數,證明:
假設 M_modN=M%N,又
(M×10+x)%N
=M×10%N+x%N
=M%N+x%N
=M_modN+x%N
所以將(M×10+x)%N壓入佇列等價於將M%N+x%N(即(M+x)%N)壓入佇列
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int vis[N]; struct node { string m; int r; }; void bfs(int n) { queue<node> q; q.push({"1",1}), vis[1]=1; while (!q.empty()) { node t=q.front(); q.pop(); if (t.r==0) {cout<<t.m; break;} for (int k=0; k<=1; k++) { int nr=(t.r*10+k)%n; if (!vis[nr]) { q.push({t.m+(k==0 ? '0' : '1'), nr}); //q.push({t.m+to_string(k), nr}); vis[nr]=1; } } } } int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int num; cin>>num; bfs(num); return 0; }
這都超時?不會吧,將to_string改成拼接字元'0'/'1',快了800ms...