/**
* poj2426 BFS
* 好像是一道AC率很低的题,非常繁琐,需要考虑的东西比较多,要认真一点做.我是看了别人的做的
* 对于+ - *三种操作,对K取模以后的结果都不耽误最后的计算;
* 而对于%,由于之前的性质,多次取模结果是一样的,因此%只会出现一次,那么就只有两种情况会出现
* 第一种就是第一个操作符就是%,第二种是第一个操作符是*,%是第二个,这种情况下就产生了0
* 而如果我们用K为模存储变量的话,一定要记得,对%操作的原数是不能先对k取模过的,否则你一定是忘了%不符合交换率
* 知道了这些,就是注意怎么做BFS的问题了,最后再回溯一下得到路径,并不算特别复杂
*/
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_NUM = 1001;
int n,k,m,big;
char op_table[5] = {'+','-','*','%',0};
char op[MAX_NUM];
struct point{
int num;
int father;
char op_pre;
} p[MAX_NUM];
bool exist[MAX_NUM];
void bfs(){
int father=0,child=1;
int dest = (n+1+big)%k;
p[0].num = (n+big)%k;
p[0].op_pre = 0;
bool finish_flag = false,repeat_flag = false;
memset(exist,0,sizeof(exist));
memset(op,0,sizeof(op));
exist[p[0].num] = true;
int tmp;
while(father<child && !finish_flag && !repeat_flag){
bool validflag=false;
for(int i=0;i<4;++i){
switch(op_table[i]){
case '*':
tmp = (p[father].num*m + big)%k;
break;
case '-':
tmp = (p[father].num-m + big)%k;
break;
case '+':
tmp = (p[father].num+m + big)%k;
break;
case '%':
//只有是作为第一个符号时,或者第一个符号是*且它作为第二个符号时
if(father == 0 || (p[father].father == 0 && p[father].op_pre == '*') ){
tmp = (father == 0) ? ((n%m+m)%m + big)%k : 0;//注意,father==0的情况,输入值不能是p[0].num,必须是n,因为前者已经对k取模了,而%不符合交换率;另一种情况,就直接赋值为0就可以了
break;
}
else{
validflag = true;
}
default:
break;
}
if(validflag)//不符合两个条件的%操作符,就不需要考虑了
continue;
if(!exist[tmp]){
exist[tmp] = true;
p[child].num = tmp;
p[child].father = father;
p[child].op_pre = op_table[i];
++child;
}
if(tmp==dest){
//output?
finish_flag = true;
break;
}
}
++father;
}
if(father == child){
cout << 0 << endl;
}
else if(finish_flag){
int x = child-1,count=0;
while(p[x].op_pre!=0){
op[count++] = p[x].op_pre;
x = p[x].father;
}
cout << count << endl;
for(int i=count-1;i>=0;--i){
cout << op[i];
}
cout << endl;
}
}
int main(){
while(cin >> n >> k >> m){
if(n==0 && k==0 && m==0){
break;
}
big = k<<20;
bfs();
}
return 0;
}
poj2426 BFS
最新推荐文章于 2019-09-12 23:17:22 发布