做完这道题,对取余的理解又进一步深刻了。
这道题直接bfs就行,关键是取余操作。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
LL ans,k;
bool vis[2010005];
char route[100000];
struct node
{
int step,pre;
LL a;
int cal;
}f[500005];
int bfs(LL n,LL m)
{
LL tmp;
memset(vis,0,sizeof(vis));
int front=0,rear=1;
f[0].a=n;f[0].step=0;
node p;
while(front<rear)
{
tmp=f[front].a;
if(tmp%k==ans)return front;
p.step=f[front].step+1;
p.pre=front;
p.cal=0;
p.a=((tmp+m)%(k*m)+k*m)%(k*m);
if(!vis[p.a])
{
f[rear++]=p;
vis[p.a]=1;
}
p.cal=1;
p.a=((tmp-m)%(k*m)+k*m)%(k*m);
if(!vis[p.a])
{
f[rear++]=p;
vis[p.a]=1;
}
p.cal=2;
p.a=((tmp*m)%(k*m)+k*m)%(k*m);
if(!vis[p.a])
{
vis[p.a]=1;
f[rear++]=p;
}
p.cal=3;
p.a=(tmp%m+m)%m%(k*m);//这里刚开始写成((tmp%m)%(m*k)+m*k)%(k*m),错了几次
if(!vis[p.a])
{
vis[p.a]=1;
f[rear++]=p;
}
front++;
}
return 0;
}
int main()
{
LL n,m;
int i,j;
while(scanf("%I64d%I64d%I64d",&n,&k,&m)!=-1)
{
if(n+k+m==0)break;
ans=((n+1)%k+k)%k;
/*LL g=gcd(n,m);
if(ans%g)
{
puts("0");
continue;
}*/
int len=bfs(n,m);
if(len==0)
{
printf("0\n");
continue;
}
printf("%d\n",f[len].step);
for(i=0;len!=0;)
{
int tmp=f[len].cal;
// printf(" %d",tmp);
if(tmp==0)
route[i++]='+';
if(tmp==1)
route[i++]='-';
if(tmp==2)
route[i++]='*';
if(tmp==3)
route[i++]='%';
len=f[len].pre;
}
//printf("\n\n\n");
//printf("i=%d\n",i);
for(j=i-1;j>=0;j--)
{
if(route[j]=='%')
printf("%%");
else
printf("%c",route[j]);
}
puts("");
}
return 0;
}