原题链接
51nod 1109
题目类型:
4
4
4级题
♦
♦
♦
♦
{\color{green}{♦♦}}{\color{lightgreen}{♦♦}}{\color{yellow}{}}{\color{orange}{}}{\color{red}{}}
♦♦♦♦
AC记录:Accepted
题目大意
给定一个自然数 N N N,找出一个 M M M,使得 M > 0 M >0 M>0且 M M M是 N N N的倍数,并且 M M M的 10 10 10进制表示只包含 0 0 0或 1 1 1。求最小的 M M M。
输入格式
输入 1 1 1个数 N N N。
输出格式
输出符合条件的最小的M。
S
a
m
p
l
e
\mathbf{Sample}
Sample
I
n
p
u
t
\mathbf{Input}
Input
4
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
100
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
无
数据范围
对于 100 % 100\% 100%的数据, 1 ≤ N ≤ 1 0 6 1\le N\le 10^6 1≤N≤106。
解题思路
此题可以用
b
f
s
bfs
bfs来解决。
我们知道,这题求的是最短的长度,所以我们可以用广搜,搜索每一个状态。
最初,状态从
1
1
1开始,然后每一次扩展,都是在这个数的后面加上一个
0
0
0或者
1
1
1。
看起来很简单,就像一道简简单单的板子题一样。
可是,这里的
n
n
n的范围可以达到
1
0
6
10^6
106,所以我们需要一些优化。
既然题目要求的是
m
m
m为
n
n
n的倍数,换一种说法就是
m
m
m能被
n
n
n整除,
m
=
0
(
m
o
d
n
)
m=0(\bmod\ n)
m=0(mod n)。所以我们只需要记录每一个状态
m
o
d
n
\bmod\ n
mod n的值,以及判重,我们就可以解出此题。
下面说一下状态转移的要点。
在状态转移时,是在后面加上一个
0
0
0或
1
1
1,所以设当前状态为
n
o
w
now
now,则接下来的状态为
10
×
n
o
w
10\times now
10×now和
10
×
n
o
w
+
1
10\times now+1
10×now+1。再根据同余原理,就可以把
×
10
\times 10
×10和
+
1
+1
+1拎出来,进而去重,最后得到答案。
注意事项:
1.在去重的时候,判断的是 m o d n \bmod\ n mod n意义下的余数,不是这个数本身!
2.在状态转移时,记得要把存储原数字的一个vector
也一起转移!
最后输出的时候,输出
f
0
f_0
f0中保存数字的vector
就行。
拓展练习:
P2841 A*B Problem
这一题是在本题的基础上加强了许多,但是据洛谷上某位神犇说,此题可以用__int128_t
水过,所以下面放的是P2841的代码,不是51nod 1109的代码。
最后,祝大家早日
上代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128_t int128;
struct obj{
obj(int128 a=0,int b=0):times(a),left(b){}
vector<int> bits;
ull times;
int left;
};
queue<obj> q;
bool a[1000010];
int n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
if(n==1)
{
cout<<"1 1"<<endl;
return 0;
}
obj st=obj(0,1);
st.bits.push_back(1);
q.push(st);
while(q.size())
{
obj now=q.front();
q.pop();
int times=now.times,left=now.left;
if(left==0)
{
// cout<<times<<" ";
for(int i=0; i<now.bits.size(); i++)
cout<<now.bits[i];
cout<<endl;
return 0;
}
for(int i=0; i<=1; i++)
{
int next_state=left*10+i;
if(a[next_state%n]==true)
continue;
obj temp=obj(times*10+next_state/n,next_state%n);
temp.bits=now.bits;
temp.bits.push_back(i);
a[next_state%n]=true;
q.push(temp);
}
}
return 0;
}
完美切题 ∼ \sim ∼