P1602 Sramoc问题 题解

思路很简单

直接爆搜

用bfs更好得到答案,从最高位往低位搜索。

但是时间会爆掉所以需要优化:对于已经搜到的某个数 $x$ ,如果有 $x \equiv y( mod\ n )$ 那么有 $ax+b \equiv ay+b$ 即下一次搜到同余的数就不用再搜索一次可以直接退出了。比如要凑到13的倍数,那么27和40只需要从27开始往下搜,搜到40直接退出即可,因为27肯定是更优的

 但是要爆long long。

高精/int128/string 均可。

毒瘤 不做了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
inline int r()
{
	int s=0,k=1;char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')k=-1;
		c=getchar();
	}
	while(isdigit(c))
	{
		s=s*10+c-'0';
		c=getchar();
	}
	return s*k;
}
int f[1000005],pw[101],n,m,t;
string nn;
int to_mod(string s,int mod)
{
	int tmp=0;
	int len=s.length();
	for(int i=0;i<len;i++)
	{
		tmp*=10;
		tmp+=(s[i]-'0');
		tmp%=mod;
	}
	return tmp;
}
string mto_string(int x)
{
	string s;
	int len=0;
	while(x)
	{
		len++;
		string tmp;
		tmp+=(char)(x%10+'0');
		s.insert(0,tmp);
		x/=10;
	}
	return s;
}
bool comp(string a,string b)//return a>b?
{
	int lena=a.length(),lenb=b.length();
	if(lena>lenb)return 1;
	else if(lena<lenb)return 0;
	else return a>=b;
}
signed main()
{
//	freopen("test.in","r",stdin);
//	freopen("a.out","w",stdout);
//	t=r();
	t=1;
	pw[0]=1;
	for(int i=1;i<=16;i++)
	pw[i]=pw[i-1]*10;
	for(int i=1;i<=t;i++)
	{
		m=r();n=r();
		nn=mto_string(n);
		queue<string>q;
		q.push("");
		while(!q.empty())
		{
			string x=q.front();			
//			cout<<"============================="<<endl;
//			cout<<"now:"<<x<<endl;
			q.pop();
			if(comp(x,nn)&&to_mod(x,n)==0)
			{
				cout<<x;
				break;
			}
			for(int i=0;i<m;i++)
			{
				if(i==0&&x=="")continue;
				string xx=x+(char)(i+'0');
				if(!f[to_mod(xx,n)])
				{
//					cout<<"push"<<xx<<" "<<to_mod(xx,n)<<endl;
					q.push(xx);
					if(comp(xx,nn))f[to_mod(xx,n)]=1;
				}
			}
		}
	}
}
posted @ 2021-07-15 21:28  lei_yu  阅读(118)  评论(0编辑  收藏  举报