九度 题目1482:玛雅人的密码
九度 题目1482:玛雅人的密码
原题OJ链接:http://ac.jobdu.com/problem.php?pid=1482
题目描述:
玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=< N <=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1。
输入:
输入包含多组测试数据,每组测试数据由两行组成。
第一行为一个整数N,代表字符串的长度(2<=N<=13)。
第二行为一个仅由0、1、2组成的,长度为N的字符串。
输出:
对于每组测试数据,若可以解出密码,输出最少的移位次数;否则输出-1。
样例输入:
5
02120
样例输出:
1
解题思路:
BFS
压入队列的每一种状态都是(strtmp, step+1),其中strtmp为交换相邻位置一次后的字符串,该字符串之前没有出现过 ,即 M.find(strtmp)==M.end() ,原先的step加上1之后把状态(strtmp,step+1)压入队列。
源代码:
#include
#include
#include
#include
using namespace std;
struct MoveStr{string str;int step;
};int size;//记录string在map集合中的位置,每加入一个新的字符串size加1
queue Q;
map<string,int> M;
/*查找所给字符串是否在集合中,若不在集合中,
则将新的结构体变量压入队列*/bool check(string str){//检查字符串是否满足2012的条件int len=str.length();for(int i=0;i3;i++){if(str[i]=='2' && str[i+1]=='0' && str[i+2]=='1' && str[i+3]=='2'){return true;}}return false;
}int BFS(){while(Q.empty()==false){MoveStr head=Q.front();//取出队首元素Q.pop();if(check(head.str)){//若字符串满足2012的条件,返回移位操作的最小次数return head.step;}for(int i=0;i1;i++){string strtmp=head.str;//移位一次,交换两个相邻字符char chartmp=strtmp[i];strtmp[i]=strtmp[i+1];strtmp[i+1]=chartmp;if(M.find(strtmp)==M.end()){/*检查移位一次之后的字符串strtmp是否在map集合中,若不在,find()函数返回M.end(),则将(strcmp,step+1)入队*/MoveStr tmp;tmp.str=strtmp;tmp.step=head.step+1;//移位次数+1Q.push(tmp);M[strtmp]=size++;}}}return -1;
}int main(){int n;while(cin>>n){while(Q.empty()==false) Q.pop();//初始化队列,清空队列M.clear();//清空一个mapsize=0;string str;cin>>str;M[str]=size++;MoveStr s;s.str=str;s.step=0;Q.push(s);int result=BFS();cout<return 0;
}
参考这位大神的解答:http://www.cskaoyan.com/thread-189023-1-1.html
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
