hdu Remainder
这道题是道很明显的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[5]="+-*%"; //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,0,sizeof(vis)); des=mod(N+1,K); int n=mod(N,mo); vis[n]=1; fa[n]=-1; cnt[n]=-1; q.push(n); while(!q.empty()) { cur=q.front(); q.pop(); if(cur%K==des) { k=0; while(fa[cur]>=0) { ope[k++]=cnt[cur]; cur=fa[cur]; } cout<<k<<endl; while(k) cout<<op[ope[--k]];//被坑哭这个地方。。。 cout<<endl; return; } for(i=0;i<4;i++) { if (i == 0)next = (cur + M) % mo; else if (i == 1)next = mod(cur - M, mo); else if (i == 2)next = cur * M % mo; else next = cur % M; if(vis[next]==0) { vis[next]=1; fa[next]=cur; cnt[next]=i; q.push(next); } } } cout<<0<<endl; } int main() { while(scanf("%d%d%d",&N,&K,&M),K) { bfs(); } return 0; }