我去,这题废了好大功夫,其实大多过程就是广搜,可有一个过程一直不明白,就是为什么模除只有两种情况,我的理解是按照顺序,所以尽可能往后,但好像不对,希望做过这题的大神帮我指点下迷津。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define M 1005
int record[M];
int n,k,m;
int ans ;
/*
a≡b(%p)
则(a+c)%p ≡ (b+c)%p;
则(a-c)%p ≡ (b-c)%p;
则(a*c)%p ≡ (b*c)%p;
所以,在这题里面,三种情况都是可以的直接用 n%k来代替了
n % m ≡ n (mod m)
但是有一个不行
为什么只有两种情况,因为,有一个字典序的要求,
还有就是,是达到那个的最短过程,那么
*/
struct node
{
int state;
int len;
int pre;
int path;
int keep;
}q[10000];
bool isAns(int state)
{
if((state + 1000*k)%k == ans) return true;
return false;
}
char getcode(int a)
{
switch(a)
{
case 0:return '+';
case 1:return '-';
case 2:return '*';
case 3:return '%';
}
}
void print(int index)
{
printf("%d\n",q[index].len);
char s[M];
int nlen = 0;
while(q[index].pre >= 0)
{
s[nlen++]=getcode(q[index].path);
index = q[index].pre;
}
for(int i = nlen-1; i >= 0; i --)
{
printf("%c",s[i]);
}
printf("\n");
}
int bfs(int state)
{
memset(q,0,sizeof(q));
memset(record,0,sizeof(record));
int top = 0,rail = 1;
if(isAns(state)) return 0;
q[top].state = (state + 1000 * k) %k;
q[top].keep = (state + 1000 * m) %m;
record[(q[top].state + 1000*k) %k] = 1;
q[top].len = 0;
q[top].pre = -1;
while(top < rail)
{
int now = q[top].state;
int nowlen = q[top].len;
for(int i = 0; i < 4; i ++)
{
switch(i)
{
case 0:
{
int temp = (now + m +1000*k)%k;
if(record[temp] == 0)
{
record[temp] = 1;
q[rail].state=temp,q[rail].len=q[top].len+1,q[rail].pre=top,q[rail].path=0;
if(isAns(temp))
{
print(rail);
return q[rail].len;
}
rail++;
}
continue;
}
case 1:
{
int temp = (now - m + 1000*k)%k;
if(record[temp] == 0)
{
record[temp] = 1;
q[rail].state=temp,q[rail].len=q[top].len+1,q[rail].pre=top,q[rail].path=1;
if(isAns(temp))
{
print(rail);
return q[rail].len;
}
rail++;
}
continue;
}
case 2:
{
int temp = (now * m + 1000*k) %k;
if(record[temp] == 0)
{
record[temp] = 1;
q[rail].keep = (q[top].keep * m ) % m;
q[rail].state=temp,q[rail].len=q[top].len+1,q[rail].pre=top,q[rail].path=2;
if(isAns(temp))
{
print(rail);
return q[rail].len;
}
rail++;
}
continue;
}
case 3:
{
if((q[top].path == 0 && q[top].len > 0) || q[top].path == 1) continue;
int temp = (q[top].keep + 1000*k) %k;
if(record[temp] == 0)
{
record[temp] = 1;
q[rail].state=temp,q[rail].len=q[top].len+1,q[rail].pre=top,q[rail].path=3;
if(isAns(temp))
{
print(rail);
return q[rail].len;
}
rail++;
}
continue;
}
}
}
top++;
}
return -1;
}
int main(int argc, char const *argv[])
{
while(scanf("%d %d %d",&n,&k,&m) != EOF)
{
if(n == 0 && m == 0 && k == 0)
break;
ans = (n+1+500*k)%k;//目标需要达到的值。
if(bfs(n) < 0) printf("0\n");
}
return 0;
}