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;
}
View Code

 

posted @ 2015-04-18 21:57  Run_For_Love  阅读(154)  评论(0编辑  收藏  举报