一个比较巧妙的题目。
开始以为要用高精度,实在不想打啊,就搜了下解题报告。
点啊点的,开了几个链接,不知怎的就点进了“于娟日记”里的文章。
哎,我惆怅的心情啊。。。。
人太过渺小,
为何我们还无止境地贪求,
能够做好一些,真正重要的事,
生命也就无憾了。
回到题目吧。
高精度嘛,果然是不用的。
利用了一点数学知识。
考虑只有+、-、*的计算,可以发现,只要每次模k,以余数为状态BFS,就能得到结果。
然而有%运算后由于n%m%k不等于n%k%m%k,以模k余数为状态就行不通了。
然后是重点:
因为是求最短序列,所以%只可能出现于两种情况:
1.第一个操作符就是%。因为如果有n+m(n-m)之类的操作,在%之前,则去掉这一段操作它们的结果是一样的。
((n+m)%m=n%m+m%m=n%m)
2.前两个操作符是*%。n*m%m===0。n是啥都不影响,也就是之前的操作无效。
特殊处理这两种情况,再用普通的+、-、*来BFS就解决了。
注意几点:
1.本题的%不是c++中的%,要结果变为正数,可以发现,只要改为(a%b+b)%b即可。
2.输出%这个符号的时候,如果你不是保存在字符变量中,那就要输出"%%"。
感谢这位大牛的题解http://blog.youkuaiyun.com/jackchongs/article/details/10971167
开始以为要用高精度,实在不想打啊,就搜了下解题报告。
点啊点的,开了几个链接,不知怎的就点进了“于娟日记”里的文章。
哎,我惆怅的心情啊。。。。
人太过渺小,
为何我们还无止境地贪求,
能够做好一些,真正重要的事,
生命也就无憾了。
回到题目吧。
高精度嘛,果然是不用的。
利用了一点数学知识。
考虑只有+、-、*的计算,可以发现,只要每次模k,以余数为状态BFS,就能得到结果。
然而有%运算后由于n%m%k不等于n%k%m%k,以模k余数为状态就行不通了。
然后是重点:
因为是求最短序列,所以%只可能出现于两种情况:
1.第一个操作符就是%。因为如果有n+m(n-m)之类的操作,在%之前,则去掉这一段操作它们的结果是一样的。
((n+m)%m=n%m+m%m=n%m)
2.前两个操作符是*%。n*m%m===0。n是啥都不影响,也就是之前的操作无效。
特殊处理这两种情况,再用普通的+、-、*来BFS就解决了。
注意几点:
1.本题的%不是c++中的%,要结果变为正数,可以发现,只要改为(a%b+b)%b即可。
2.输出%这个符号的时候,如果你不是保存在字符变量中,那就要输出"%%"。
感谢这位大牛的题解http://blog.youkuaiyun.com/jackchongs/article/details/10971167
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define NN 30
#define MM 1010
int tsv[MM],tt[MM],fa[MM],fao[MM],vis[MM];
int asv[MM];
char ch[]={'0','+','-','*','%'};
int mod(int a,int b){return (a%b+b)%b;}
int bfs(int n,int endsta,int k,int m,int func){
int cnt;
if (func==0){
cnt=0;
}
else if (func==1){
cnt=1;tsv[1]=4;
}
else if (func==2){
cnt=2;tsv[1]=3;tsv[2]=4;
}
if (n==endsta) return cnt;
queue<int> q;
q.push(n);
memset(vis,0,sizeof(vis));
vis[n]=1;
fa[n]=-1;
fao[n]=-1;
int u,v;
while(!q.empty()){
u=q.front();
q.pop();
if (u==endsta) break;
if (!vis[v=mod(u+m,k)]){
vis[v]=1;
q.push(v);
fa[v]=u;
fao[v]=1;
}
if (!vis[v=mod(u-m,k)]){
vis[v]=1;
q.push(v);
fa[v]=u;
fao[v]=2;
}
if (!vis[v=mod(u*m,k)]){
vis[v]=1;
q.push(v);
fa[v]=u;
fao[v]=3;
}
}
if (!vis[endsta]) return -1;
int p=endsta,tc=0;
while(fa[p]!=-1){
tt[++tc]=fao[p];
p=fa[p];
}
int i;
for(i=tc;i>=1;--i){
tsv[++cnt]=tt[i];
}
return cnt;
}
int main(){
int i;
int ans,cnt;
int n,k,m;
while(1){
scanf("%d%d%d",&n,&k,&m);
if (n==0&&k==0&&m==0) break;
ans=1000000;
cnt=bfs(mod(n,k),mod(n+1,k),k,m,0);//normal
if (cnt>0) {
ans=cnt;
for(i=1;i<=cnt;++i){
asv[i]=tsv[i];
}
}
cnt=bfs(0,mod(n+1,k),k,m,2);//*%...
if (cnt!=-1&&cnt<ans){
ans=cnt;
for(i=1;i<=cnt;++i){
asv[i]=tsv[i];
}
}
cnt=bfs(mod(mod(n,m),k),mod(n+1,k),k,m,1);//%...
if (cnt!=-1&&cnt<ans){
ans=cnt;
for(i=1;i<=cnt;++i){
asv[i]=tsv[i];
}
}
if (ans>10000) puts("0");
else {
printf("%d\n",ans);
for(i=1;i<=ans;++i){
printf("%c",ch[asv[i]]);
}
printf("\n");
}
}
return 0;
}