NEERC2018A(bfs+dfs+贪心+记忆化)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qkoqhh/article/details/83351099

链接:http://codeforces.com/contest/1070

题意:求出最小的正整数,使它满足数位和为s,且可以被d整除

一道不错的题。。

这个显然可以把(d,s)作为状态来存,可是数字太大存不下,但是存个长度还是可以的,然后直接做bfs之后就可以得到目标数字的长度了。。然而这个数字没办法确定,因为转移的时候不能把之前的决策方案存下来,即当前状态的高位数字我们并不知道,这样导致了在位数相同的时候我们无法确定数字的大小关系,在bfs的过程中就无法保存最优状态。。

然而还是能求出长度的,这给解决问题带来了一定的便利。。

仔细思考可以发现,通过bfs,我们已经把上面的所有状态给建成了一个分层图,即当前状态只能往长度比他大1的状态进行转移。。那么可以从高位开始贪心,然后直接做dfs,然而这个代价貌似还是很大。。其实如果当前的贪心策略能到达目标状态(0,s),那么这个一定是最优状态,如果不行,说明我们从这个状态出发经过的dfs树都不能到达目标状态,那么只需记忆化标记一下就可以了。。最多标记次数不超过d*s。。

因此总复杂度为O(ds)

#include<bits/stdc++.h>
using namespace std;
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge*j=h[x];j;j=j->next)
#define succ(x) (1<<(x))
#define sqr(x) ((x)*(x))
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define lowbit(x) (x&(-x))
#define eps 1e-8
#define mid (x+y>>1)
#define NM 5005
const ll inf=1e9+7;
const double pi=acos(-1);
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}



struct tmp{int x,y;};
int n,m,d[5005][505],c[NM],tot;
bool v[5005][505];
queue<tmp>q;

bool dfs(int x,int y){
    if(x==n&&y==0)return true;
    inc(k,0,9)if(x+k<=n&&!v[x+k][(y*10+k)%m]&&d[x+k][(y*10+k)%m]==d[x][y]+1){
	c[++tot]=k;
	if(dfs(x+k,(y*10+k)%m))return true;
	tot--;
    }
    v[x][y]++;return false;
}

int main(){
    m=read();n=read();
    inc(i,0,n)inc(j,0,m)d[i][j]=inf;
    q.push(tmp{0,0});d[0][0]=0;
    while(!q.empty()){
	tmp t=q.front();q.pop();v[t.x][t.y]=false;
	inc(k,0,9){
	    int x=t.x+k,y=(t.y*10+k)%m;
	    if(x>n)break;
	    if(d[x][y]>d[t.x][t.y]+1){
		d[x][y]=d[t.x][t.y]+1;
		if(!v[x][y])q.push(tmp{x,y}),v[x][y]++;
	    }
	}
    }
    //printf("%d\n",d[n][0]);
    if(d[n][0]==inf)return 0*printf("-1\n");
    dfs(0,0);
    //printf("%d\n",tot);
    inc(i,1,tot)printf("%d",c[i]);putchar('\n');
    return 0;
}

A. Find a Number

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given two positive integers d

and s. Find minimal positive integer n which is divisible by d and has sum of digits equal to s

.

Input

The first line contains two positive integers d

and s (1≤d≤500,1≤s≤5000

) separated by space.

Output

Print the required number or -1 if it doesn't exist.

Examples

Input

Copy

13 50

Output

Copy

699998

Input

Copy

61 2

Output

Copy

1000000000000000000000000000001

Input

Copy

15 50

Output

Copy

-1

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/83351099