给定 n,m,k(<1000)
定义的%:a = b * q + r (q > 0 and 0 <= r < q), then we have a % q = r. (取模后为正整数)
n可以+,-,*,% m, 求最少多少步骤可以使得 n%k = (初始的n+1)%k
思路:
bfs,最后的结果都要%k,避免数过大我们中途每次求得的值都要取%
但是中途也可能%m,所有我们可以先%(k*m) ,易证 a%m = a%(m*k)%m
k*m的范围也在1000000内这样是可行的
收获:
对于一个数取模的理解,取模满足+,-,*的线性运算,但是不满足%,/的运算
代码如下:
/* ID: meixiny1 PROG: test LANG: C++11 */ #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <climits> #include <string> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map> #include <sstream> #include <cctype> using namespace std; typedef long long ll; typedef pair<int ,int> pii; #define MEM(a,b) memset(a,b,sizeof a) #define CLR(a) memset(a,0,sizeof a); const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; #define PI 3.1415926 //#define LOCAL char ch[4]={'+','-','*','%'}; struct node { int cnt; int which; int where; int last; }dp[1000005]; bool vis[1000005]; void print(int now){ if(dp[now].which==-1)return; print(dp[now].last); printf("%c",ch[dp[now].which]); } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif int n,k,m; while(cin >> n >> k >> m &&(n || k || m)){ MEM(vis,0); for(int i=0;i<=1000000;i++)dp[i].cnt = inf; int ans = ((n+1)%k+k)%k; int end; node a,b; a.cnt = 0, a.which = -1, a.where = (n%(k*m)+k*m)%(k*m); vis[a.where] = 1; queue<node> q; q.push(a); int ok = 0; while(!q.empty()){ a = q.front();q.pop(); dp[a.where] = a; if(a.where%k == ans){ ok = 1; end = a.where; break; } if(!vis[(a.where+m)%(k*m)])vis[(a.where+m)%(k*m)]=1,b.cnt = a.cnt+1, b.which = 0, b.where = (a.where+m)%(k*m), b.last = a.where, q.push(b); if(!vis[((a.where-m)%(k*m)+k*m)%(k*m)])vis[((a.where-m)%(k*m)+k*m)%(k*m)]=1,b.cnt = a.cnt+1, b.which = 1, b.where = ((a.where-m)%(k*m)+k*m)%(k*m), b.last = a.where, q.push(b); if(!vis[(a.where*m)%(k*m)])vis[(a.where*m)%(k*m)]=1,b.cnt = a.cnt+1, b.which = 2, b.where = (a.where*m)%(k*m), b.last = a.where, q.push(b); if(!vis[(a.where%m)%(k*m)])vis[(a.where%m)%(k*m)]=1,b.cnt = a.cnt+1, b.which = 3, b.where = (a.where%m)%(k*m), b.last = a.where, q.push(b); } if(ok){ printf("%d\n",dp[end].cnt); print(end); printf("\n"); } else{ printf("0\n"); } } return 0; }