Description
话说员工们整理好了筷子之后,就准备将快餐送出了,但是一看订单,都傻眼了:订单上没有留电话号码,只写了一个sramoc(k,m)函数,这什么东西?什么意思?于是餐厅找来了资深顾问团的成员,YQ,SC,HQ,经过大量的查阅,大家获得了一些信息,Sramoc ( K , M ) 表示用数字0、1、2…、K-1组成的自然数中能被M整除的最小数。例如 K=2,M=7的时候,Sramoc( 2 , 7 ) = 1001。自然电话号码就是1001,为了尽快将快餐送出,电脑组的童鞋们埋头算起了这个齐葩的号码。。。
Input
第1行为两个整数 k, m (2≤k≤10,0≤m≤1000)。
Output
仅1行,那个电话号码(最小的数)。
Sample
输入样例#1:
2 7
输出样例#1:
1001
Solution
我觉得这道题有点神奇
暴力会超时(比如极端数据2 999)
深搜也会超时,因为没有办法判断是不是最小的,必须搜完
可以用宽搜
把已经得到的数放在一个队列里面,每次取出一个,然后在后面接一个数
因为可以在乘法和加法的时候取模,所以最多会有m个数
数位是从高位到低位的,枚举是从小到大的,所以第一次找到余数为0的时候,那个数是最小的
因为要输出这个数,所以我用了一个链表,方便新加数,并且被转移到的数可以直接利用转移的数
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#define lo long long
using namespace std;
int q[1011],fir[1011],nxt[1011],to[1011],out[101],k,m,e=0;
bool ex[1011];
int read()
{
int ans=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
return ans*f;
}
void solve()
{
int h=1,t=0,o,lim,zc;
q[++t]=0;ex[0]=1;
while(h<=t)
{
o=q[h++];
lim=o==0? 1:0;
for(int i=lim;i<k;i++)
{
zc=(o*10%m+i)%m;
if(!ex[zc]||zc==0)
{
nxt[++e]=fir[o];
fir[zc]=e;
to[e]=i;
ex[zc]=1;
q[++t]=zc;
}
if(zc==0)
return;
}
}
}
int main()
{
int w=0;
k=read();m=read();
solve();
for(int i=fir[0];i;i=nxt[i])
out[++w]=to[i];
for(int i=w;i>=1;i--)
putchar(out[i]+'0');
return 0;
}