hdu Remainder

时间:2023-03-08 21:15:59

这道题是道很明显的bfs题。因为对数论没什么研究 ,所以这道题目里的两个关键点并不知道,看了别人的题解才知道 。

1、为避免取模后出现负数,采用:x%y=(x%y+y)%y

2、全部采用对m*k取模后的值作为下标,这个是最关键的。

还要注意操作符的回溯数组,小细节被坑哭。。。

#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"cmath"
#include"string"
#include"string.h"
#include"queue"
#define mx 1000005
using namespace std;
char op[]="+-*%";
//vis用来标记n值是否已出现过,fa[i]记录的是i的前一个操作数,cnt用来记录操作符
int vis[mx],fa[mx],cnt[mx],ope[mx];
int N,K,M; int mod(int a,int b)
{
return (a%b+b)%b;
} void bfs()
{
int mo=K*M,i,cur,next,des,k;
queue<int>q;
while(!q.empty()) q.pop();
memset(vis,,sizeof(vis));
des=mod(N+,K);
int n=mod(N,mo);
vis[n]=;
fa[n]=-;
cnt[n]=-;
q.push(n);
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur%K==des)
{
k=;
while(fa[cur]>=)
{
ope[k++]=cnt[cur];
cur=fa[cur];
}
cout<<k<<endl;
while(k) cout<<op[ope[--k]];//被坑哭这个地方。。。
cout<<endl;
return;
}
for(i=;i<;i++)
{
if (i == )next = (cur + M) % mo;
else if (i == )next = mod(cur - M, mo);
else if (i == )next = cur * M % mo;
else next = cur % M;
if(vis[next]==)
{
vis[next]=;
fa[next]=cur;
cnt[next]=i;
q.push(next);
}
}
}
cout<<<<endl;
}
int main()
{
while(scanf("%d%d%d",&N,&K,&M),K)
{
bfs();
}
return ;
}