【1496】页 {广度优先搜索+哈希//最短路}

题目


解题思路

      这道题可以直接用广度优先搜索做,但是在比赛的时候,并没有做这道题,遗憾,只拿了10分打表分。因题目确保只有九个数,那么可以将这些160到179的数化成1到9,即方便了判重,也避免了数组越界。然后就执行(left 和 right)的命令,注意细节即可。

     //这道题还可以用最短路做,将每种状态化作9进制数,然后每个数(点)之间求最短路。

代码(广度优先搜索+哈希)

#include<cstdio>
#include<map>
#include<algorithm>
#include <iostream>
using namespace std; 
map<int,bool>w; 
int n,mid,q,d,a[10][362881],b[10],c[10],fa[362881],head,tail; 
int fdd()
{ 
    int answ=0; //组合成一个数
	for (int i=n;i>=1;i--)
	 answ=answ*10+a[i][tail];
	return answ; 
}
bool mb()
{
	bool r=true; //判断是否达到题意
	for (int i=1;i<n;i++)
	 if (a[i+1][tail]<a[i][tail]) r=false; 
	if (r==false) return 0; else return 1; 
}
void left()
{
	int e=a[mid][head]; tail++;
	for (int i=2;i<=mid;i++)
	 a[i][tail]=a[i-1][head];
	for (int i=mid+1;i<=n;i++)
	 a[i][tail]=a[i][head]; 
	 a[1][tail]=e; 
}
void right()
{
	int e=a[mid][head]; tail++;
	for (int i=n-1;i>=mid;i--)
	 a[i][tail]=a[i+1][head];  
	for (int i=mid-1;i>=1;i--)
	 a[i][tail]=a[i][head]; 
	 a[n][tail]=e;
}
int tgg(int x)
{ 
	if (fa[x]!=-1) tgg(fa[x]); 
	d++; //回溯
	return d; 
}
int main()
{
	scanf("%d",&n); 
	mid=(1+n)/2; 
    for(int i=1;i<=n;i++)
     scanf("%d",&b[i]),c[i]=b[i]; 
    sort(c+1,c+n+1); 
    for (int i=1;i<=n;i++)
     for (int j=1;j<=n;j++)
     if (c[i]==b[j]) {b[j]=i; break;}
    for (int i=1;i<=n;i++)
     a[i][1]=b[i]; 
    head=0; tail=1;   fa[1]=-1;
    do
    {
    	head++; 
        left(); q=fdd(); 
        if (mb()) 
		{
     	  printf("%d",tgg(head)); 
     	  return 0; 
        }
    	if (!w[q])
    	{
    	 fa[tail]=head; 
    	 w[q]=1; 
		}  else tail--;
		
		right(); q=fdd();
		if (mb()) 
		{
     	  printf("%d",tgg(head)); 
     	  return 0; 
        }
		if (!w[q])
		{ 
		 fa[tail]=head; 
		 w[q]=1; 
		}  else tail--;	
	}while (head<tail);	//主过程
	puts("No Answer");
}


猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/80955094