zoukankan      html  css  js  c++  java
  • poj1184 聪明的打字员(BFS剪枝)

    http://poj.org/problem?id=1184

    用字符串s存下数字,并把光标位置做一个字符加到s末尾,用map做标记状态是否出现过,然后bfs即可。

    不剪枝是过不了的,考虑的两种交换操作都不涉及到2,3,4,5位置,所以这几个位置只能通过up,down来改变。

    如果这几个位置是和目标状态是不一样的,那肯定是用up,down操作是最优的,而不会执行left,right操作。

    所以这几个位置只有在和目标状态一样时做left,right操作。

    #include <iostream>
    #include <map>
    #include <string> 
    #include <queue> 
    using namespace std;
    struct point
    {
    	int step;
    	string s;
    };
    string e;
    map<string,int> my;
    queue<point> q;
    int BFS(point st)
    {
    	point t,tt; string ss; int i;
    	while(!q.empty()) q.pop();
    	q.push(st);  my[st.s]=1;
    	while(!q.empty())
    	{
    		t=q.front(); q.pop();
    		
    		for(ss=t.s,i=0;i<6;i++)
    			if(ss[i]!=e[i]) break;
    		if(i==6) return t.step;
    		ss=t.s; swap(ss[0],ss[ss[6]-'0']);//Swap0:
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}
    		ss=t.s; swap(ss[5],ss[ss[6]-'0']); //Swap1
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}
    		ss=t.s; if(ss[ss[6]-'0']!='9'&&ss[ss[6]-'0']!=e[ss[6]-'0']) ss[ss[6]-'0']+=1; //Up:
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}
    		ss=t.s; if(ss[ss[6]-'0']!='0'&&ss[ss[6]-'0']!=e[ss[6]-'0']) ss[ss[6]-'0']-=1;//Down: 
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}
    		ss=t.s; 
    		if(ss[6]-'0'!=0)//left
    		{
    			if(ss[6]!='5') //1 2 3 4位置相同才能移动光标 
    			{
    				if(ss[ss[6]-'0']==e[ss[6]-'0']) ss[6]-=1; 
    			}
    			else ss[6]-=1;
    		}
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}
    		ss=t.s; 
    		if(ss[6]-'0'!=5)//Right
    		{
    			if(ss[6]!='0') //1 2 3 4位置相同才能移动光标 
    			{
    				if(ss[ss[6]-'0']==e[ss[6]-'0']) ss[6]+=1; 
    			}
    			else ss[6]+=1;
    		}
    		if(!my.count(ss))
    		{
    			tt.s=ss; tt.step=t.step+1;
    			q.push(tt); my[ss]=1;
    		}	
    	}
    }
    int main(int argc, char *argv[])
    {
    	point st;
    	while(cin>>st.s>>e)
    	{
    		my.clear();
    		st.s+='0'; st.step=0;
    		cout<<BFS(st)<<endl;
    	}
    	return 0;
    }


  • 相关阅读:
    数据文件对应的磁盘坏掉了,没有归档,没有备份
    Oracle OEM重建
    Verilog编码指南
    UART串口协议
    信号完整性以及串扰
    Perl-由报表转命令(展讯2015)
    论文-ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
    时序路径分析模式
    后端设计各种设计文件格式说明
    Verilog-小数分频器(1.5)实现(待写)
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3339508.html
Copyright © 2011-2022 走看看