HDU6223(2017acm-沈阳) BFS+剪枝(好题)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=6223


题目大意:

给你一个n位的数字串,第i位可以跳到第(i*i+1)的位子上;

让你从这个数字串的任何位置跳n次;

求能跳的最大数字;

n最多一万位;


思路

BFS

先找最大的一位/几位作为头结点;

然后BFS;

剪枝1:现在搜的数不可能比答案大了

剪枝2:当前层访问过了;


上代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
/*------------------------------------------------------------------------------*/
struct node{
	int num,wz,clock;
	node(){}
    node(int num,int wz,int clock):num(num),wz(wz),clock(clock){}   
	 // 为了下面赋值方便所以这样打 
};

int T,t,i,n,da;
char st[150010];
int a[150010],next[150010],ans[150010],bfn[150010];
// ans[]存放答案;
// bfn[]表示访问时间,或者可以当成时间戳,在答案的第几位,搜索的第几层;
// 这是本代码精彩之处;  


struct cmp{
    bool operator()(node a,node b)
    {
        if(a.clock!=b.clock) return a.clock>b.clock;       
        else if(a.num!=b.num) return a.num<b.num;
        return a.wz>b.wz;
    }
};           //  向后移动的条件;
// 放在前面的数:时间短的,数字大的,在前面的 
// 优先队列+BFS的题目还真是第一次做 
priority_queue<node,vector<node>,cmp> q;
/*------------------------------------------------------------------------------*/

void BFS()
{
        memset(bfn,-1,sizeof(bfn));
        memset(ans,-1,sizeof(ans));
		while(!q.empty())
        {
            node t=q.top();
			q.pop();
            if(ans[t.clock]==-1) ans[t.clock]=t.num;   
            if(ans[t.clock]>t.num) continue;      //剪枝1,小的 
            if(bfn[t.wz]<t.clock) bfn[t.wz]=t.clock;    // 剪枝2,慢的 
            else continue;
            if (t.clock==n-1) continue;
            q.push(node(a[next[t.wz]],next[t.wz],t.clock+1));
        }	
        cout<<"Case #"<<t<<": ";
        for (int j=0; j<n; j++) printf("%d",ans[j]); cout<<endl; 
}

/*------------------------------------------------------------------------------*/
int main()
{
	scanf("%d",&T);
	for (t=1; t<=T; t++)
	{
		scanf("%d\n",&n);
		gets(st);
		da=0;
		for (i=0; i<strlen(st); i++)
		{
		   a[i]=st[i]-'0';
		   if (a[i]>da) da=a[i];
		   next[i]=(((ll)i*(ll)i+1)%(ll)n);
	    }  //寻找第一个起始位置 
		for (i=0; i<n; i++) if (a[i]==da){
			node temp; temp.num=a[i],temp.wz=i,temp.clock=0;
			q.push(temp);
		}   // 入队 
		BFS();
	}	
} 



猜你喜欢

转载自blog.csdn.net/WJHKDGHP/article/details/78804811
今日推荐