题目描述
话说员工们整理好了筷子之后,就准备将快餐送出了,但是一看订单,都傻眼了:订单上没有留电话号码,只写了一个sramoc(k,m)函数,这什么东西?什么意思?于是餐厅找来了资深顾问团的成员,YQ,SC,HQ,经过大量的查阅,大家获得了一些信息,Sramoc ( K , M ) 表示用数字0、1、2…、K-1组成的自然数中能被M整除的最小数。例如 K=2,M=7的时候,Sramoc( 2 , 7 ) = 1001。自然电话号码就是1001,为了尽快将快餐送出,电脑组的童鞋们埋头算起了这个齐葩的号码。。。
输入输出格式
输入格式:
第1行为两个整数 k, m (2≤k≤10,0≤m≤1000)。
输出格式:
仅1行,那个电话号码(最小的数)。
输入输出样例
输入样例#1: 复制
2 7
输出样例#1: 复制
1001
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
#define MAXN 1005
int K,M;
bool vis[MAXN];
void bfs()
{
int i;
queue<long long> q;
queue<vector<int> > q2;
vector<int> s;
for(i=1;i<=K-1;i++) //i表示的是余数,所以不能为0,为0就直接结束了(下面)
{
q.push(i%M); //这里取余是已经判断出传递对象了
vis[i%M]=true;
s.push_back(i);
q2.push(s); // 队列在这个循环中都是没出队列的
s.pop_back(); //但不定数组每次都要重置 ,不定数组存的是一个数字串
} //利用广搜处理暴力枚举k^a种情况a确定大小
long long u,k;
while(!q.empty()) //出队列才是广搜的开始
{
u=q.front();
q.pop();
s=q2.front();
q2.pop();
for(i=0;i<=K-1;i++) //枚举K,和暴力一致(K>=2&&K<=10,m>=0&&m<=1000) //以暴力为基础思想的还是用 long long比较保险
{ //利用同余简化暴力枚举的次数,但枚举形式不变
k=u*(10%M)+i%M; //(x*k+y)mod m=((x mod m)*(k mod m)+(y mod m) ) mod m .//本题的k为10
// ((x*k+y)*k+i) mod m==(((x*k+y) mod m)*(k mod m)+i mod m) mod m==上述,所以可以迭代
s.push_back(i); // 所以每次 u取(x*k+y) mod m,也就是k%M
if(k%M==0) //用同余就考虑两种对比情况,找到传递的对象
{
for(unsigned int j=0;j<s.size();j++) printf("%d",s[j]);
cout<<endl;
return;
}
else if(vis[k%M]==0) //判断传递对象是否有
{
vis[k%M]=true;
q.push(k%M);
q2.push(s);
}
s.pop_back(); //每次压入不定数组都有删除最后一个元素的操作,把这个i去掉,同层枚举吧
}
}
}
//不用同余的暴力枚举
/*
while(!q.empty())
{
u=q.front();
q.pop();
s=q2.front();
q2.pop();
for(i=0;i<=K-1;i++)
{
k=u*10+i; //不同点1
s.push_back(i);
if(k%M==0) //不同点2
{
for(unsigned int j=0;j<s.size();j++) printf("%d",s[j]);
cout<<endl;
return;
}
q.push(k); //不同点3
q2.push(s);
s.pop_back();
}
}
所以利用同余就是抓住了 (x*k+y)mod m=((x mod m)*(k mod m)+(y mod m) ) mod m,进行迭代
*/
int main()
{
cin>>K>>M;
bfs();
return 0;
}