CodeForces - 1070 A Find a Number(记忆化宽搜)

http://codeforces.com/contest/1070

题意:给出两个正整数 d 和 s ,求最小的正整数 n ,使得 n 为 d 的倍数,且 n 的每一位加起来等于 s 。

思路

不难想到搜索,但是 n 可能很大,以至于超出 long long 的范围,显然这个题还没有复杂到综合考察大数运算。所以在这里使用一个带有数论知识的DP。vis[i][j] i为余数 j为位数和。根据位数进行BFS

1.位数和等于s ,mod等于d的时候是答案 

2.如果位数和>s就不入队

3.剩下的每次入队前都mod d ,加上那位数。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map> 
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
int vis[510][5010];
struct node{
	int mod; 
	int sum;
	string str;
	node(){};
	node(int mod_,int sum_,string str_)
	{
		mod=mod_;
		sum=sum_;
		str=str_;
	}
}r,rr;
int s,d;
string bfs()
{
	queue<node>q;
	q.push(node(0,0,""));
	while(q.size())
	{
		r=q.front();
		q.pop();
		if(r.mod==0&&r.sum==s)
		{
			return r.str;
		}
		if(r.sum<=s)
		{
			for(int i=0;i<10;i++)
			{
				int mod=(r.mod*10+i)%d;
				int sum=r.sum+i;
				if(!vis[mod][sum]) // 判断之前是否出现过
				迷了好久 当时一直在想 是否存在两个不同的数 他们的余数相等 各个位数相加的和相同 
				这两个数应该都放进去 继续接下来的操作啊 后来发现并不是这样 这道题还和d 和 s相关
				如果他们的余数 和 相等的数 我们接下来干的时候+i 这样的话这些数还是相同 所以没有必要
				并且我们是0-9开始遍历的 所以一开始拿到的就是最小的数 
				{
					vis[mod][sum]=1;
					q.push(node(mod,sum,r.str+(char)(i+'0')));
				}
			} 
		}
	}
	return "-1";
}
int main()
{
	cin>>d>>s;
	cout<<bfs()<<endl;
	return 0;
}

好像关于找数字的题 如果模拟不出来 就得用 搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值