1. 程式人生 > >HDU 1104 Remainder(BFS路徑記錄+數論)

HDU 1104 Remainder(BFS路徑記錄+數論)

每次 mem urn 我們 這樣的 ans to do con .cn

Remainder

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4337 Accepted Submission(s): 1095


Problem Description Coco is a clever boy, who is good at mathematics. However, he is puzzled by a difficult mathematics problem. The problem is: Given three integers N, K and M, N may adds (‘+’) M, subtract (‘-‘) M, multiples (‘*’) M or modulus (‘%’) M (The definition of ‘%’ is given below), and the result will be restored in N. Continue the process above, can you make a situation that “[(the initial value of N) + 1] % K” is equal to “(the current value of N) % K”? If you can, find the minimum steps and what you should do in each step. Please help poor Coco to solve this problem.

You should know that if a = b * q + r (q > 0 and 0 <= r < q), then we have a % q = r.

Input There are multiple cases. Each case contains three integers N, K and M (-1000 <= N <= 1000, 1 < K <= 1000, 0 < M <= 1000) in a single line.

The input is terminated with three 0s. This test case is not to be processed.

Output For each case, if there is no solution, just print 0. Otherwise, on the first line of the output print the minimum number of steps to make “[(the initial value of N) + 1] % K” is equal to “(the final value of N) % K”. The second line print the operations to do in each step, which consist of ‘+’, ‘-‘, ‘*’ and ‘%’. If there are more than one solution, print the minimum one. (Here we define ‘+’ < ‘-‘ < ‘*’ < ‘%’. And if A = a1a2...ak and B = b1b2...bk are both solutions, we say A < B, if and only if there exists a P such that for i = 1, ..., P-1, ai = bi, and for i = P, ai < bi)

Sample Input 2 2 2 -1 12 10 0 0 0

Sample Output 0 2 *+

Author Wang Yijie

Recommend Eddy | We have carefully selected several similar problems for you: 1195 1016 1175 1180 1043 以下有部分引用kuangbin大神 分析:題目要求最小步數,很容易想到用BFS,這裏註意一下 %與mod的區別:%出來的數有正有負,符號取決於左操作數。。。而mod只能是正(因為a = b * q + r (q > 0 and 0 <= r < q), then we have a mod q = r 中r要大於等於0小於q)。

所以要用%來計算mod的話就要用這樣的公式:a mod b = (a % b + b) % b

括號裏的目的是把左操作數轉成正數

要讓BFS記錄的狀態盡量的少,常常會想到在每個地方都%k,記錄每次%k後的值 但是這題會涉及到%k和%m, 如果記n = 2, m = 8, k =3. 則((n * m)%k % m)%k = 1 而(n * m % m)%k = 0。所以我們不能將每一步記錄的值都%k; 為了不影響後面 所以我們將%km(這裏其實用k和m的公倍數就可以了)後的值進行狀態記錄,關於路徑記錄則用string進行 代碼如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
 int  n,k,m;
 int km;
int vis[1000100];
struct node
{
    int x;
    int  step;
    string path;
    int num;
};
queue<node>Q;
node bfs()
{
    int p,q;
  node a,next,fail;
  a.x=n;
  a.step=0;
  Q.push(a);
  q=((n+1)%k+k)%k;
  while(!Q.empty())
  {
   a=Q.front();
   Q.pop();
   p=(a.x%k+k)%k;
    // cout<<p<<" "<<q<<endl;
   if(p==q){
 //   cout<<p<<endl;
   return a;
   }
    next.step=a.step+1;
    next.x=((a.x+m)%km+km)%km;
    next.path=a.path+‘+‘;
    if(!vis[next.x])
    {
        vis[next.x]=1;
        Q.push(next);
    }

     next.x=((a.x-m)%km+km)%km;
    next.path=a.path+‘-‘;
    if(!vis[next.x])
    {
        vis[next.x]=1;
        Q.push(next);
    }

      next.x=(a.x*m%km+km)%km;
    next.path=a.path+‘*‘;
    if(!vis[next.x])
    {
        vis[next.x]=1;
        Q.push(next);
    }
           next.x=(a.x%m+m)%m%km;
    next.path=a.path+‘%‘;
    if(!vis[next.x])
    {
        vis[next.x]=1;
        Q.push(next);
    }

  }
  fail.step=0;
  return fail;
}
int main()
{
  //   freopen("1.out","w",stdout);
    while(scanf("%d%d%d",&n,&k,&m)!=EOF){
    if(n==0&&k==0&&m==0)break;
         km=m*k;
       node ans;
     memset(vis,0,sizeof(vis));
       while(!Q.empty())Q.pop();
       ans=bfs();
       if(ans.step==0)puts("0");
       else{
          printf("%d\n",ans.step);
          cout<<ans.path<<endl;}
   }

   return 0;
}
 

HDU 1104 Remainder(BFS路徑記錄+數論)