洛谷 1602 Sramoc问题

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;
}
 
posted @ 2017-10-05 15:13  o00v00o  阅读(309)  评论(0编辑  收藏  举报