zoukankan      html  css  js  c++  java
  • 【UVa】11882 Biggest Number(dfs+剪枝)

    题目

    题目
     


    分析

    典型搜索,考虑剪枝。
    统计一下联通分量。

    • 1、本位置能够达到所有的点的数量加上本已有的点,还没有之前的结果长,直接返回。

    • 2、当本位置能够达到所有的点的数量加上本已有的点与之前的结果一样长,就把联通分量里的点从大到小排序。如果这样都比Ans小,那么直接返回。

    前两种是大多人用的,这两个剪枝有了,AC不是问题。

    • 3、如果本图没有障碍物,那么意味着所有点联通,那么结果必定是从整张图的最大值出发的,非最大值,就不用考虑了。
      这个是我自己想的,大约能剪 40-80 ms。

    个人觉得本题较坑,一开始我判联通分量用的是dfs,疯狂Tle。。。改成bfs 460ms。再瞎搞剪到400ms。
    这个速度不算快,我觉得是我常数太大了,或者写法不太好。
     


    代码

    #include <cstring>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    int r,c,L,num;
    int vis[33][33],vis2[33][33];
    int dx[5]={1,-1,0,0},dy[5]={0,0,1,-1};
    
    vector<char> Ans,v;
    char map[33][33];
    
    bool cmp(int x,int y){ return x>y; }
    
    bool in(int x,int y)
    {
    	if(x>=0 && x<r && y>=0 && y<c) return true;
    	return false;
    }
    
    void GetNum(int sx,int sy)
    {
    	memset(vis2,0,sizeof(vis2)); v.clear();
    	queue<int> q;
    	q.push(sx*33+sy);
    	while(!q.empty())
    	{
    		int m=q.front(); q.pop();
    		int x=m/33,y=m%33;
    		for(int i=0;i<4;i++)
    		{
    			int px=x+dx[i],py=y+dy[i];
    			if(in(px,py) && map[px][py]!='#' && !vis[px][py] && !vis2[px][py])
    			{
    				v.push_back(map[px][py]);
    				vis2[px][py]=1;
    				q.push(px*33+py);
    			}
    		}
    		
    	}
    	L=v.size();
    }
    
    int small(vector<char> a,vector<char> b)
    {
    	for(int i=0;i<min(a.size(),b.size());i++)
    	{
    		if(a[i] < b[i]) return 1;
    		if(a[i] > b[i]) return 0;
    	}
    	return 2;
    }
    
    void dfs(int x,int y,vector<char> S)
    {
    	if(((small(S,Ans)==0 && S.size() == Ans.size()) && S.size()) || S.size() > Ans.size()) Ans=S;
    	
    	GetNum(x,y); 
    	
    	if(S.size() + L < Ans.size()) return;
    	if(S.size() + L == Ans.size()) 
    	{
    		int q=small(S,Ans);
    		if(q==1) return;
    		if(q==0) goto l1;
    		sort(v.begin(),v.end(),cmp);
    		int f=0;
    		for(int i=0;i<L;i++)
    		{
    			if(v[i] < Ans[i+S.size()])
    			{
    				f=1; break;
    			}
    			if(v[i] > Ans[i+S.size()]) break;
    		}
    		if(f==1) return;
    	}
    	
    l1:	for(int i=0;i<4;i++)
    	{
    		int px=x+dx[i],py=y+dy[i];
    		if(in(px,py) && map[px][py]!='#' && !vis[px][py])
    		{
    			vis[px][py]=1; S.push_back(map[px][py]);
    			dfs(px,py,S);
    			vis[px][py]=0; S.pop_back();
    		}
    	}
    }
    
    int main()
    {
    	while(scanf("%d%d",&r,&c)==2 && r && c)
    	{
    		int num=0,maxnum=-1;
    		Ans.clear(); v.clear();
    		memset(vis,0,sizeof(vis));
    		
    		for(int i=0;i<r;i++)
    		{
    			scanf("%s",map[i]);
    			for(int j=0;j<c;j++)
    				if(map[i][j]=='#') num++;
    				else maxnum=max(maxnum,map[i][j]-'0');
    		}
    		for(int i=0;i<r;i++)
    		{
    			for(int j=0;j<c;j++)
    			{
    				vector<char> S;
    				if(map[i][j]!='#')
    				{
    					if(num==0 ) if(map[i][j]<maxnum+'0') continue;
    					vis[i][j]=1; S.push_back(map[i][j]);
    					dfs(i,j,S);
    					vis[i][j]=0;
    				}
    			}
    		}
    		for(int i=0;i<Ans.size();i++)
    		printf("%c",Ans[i]);
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    5、打断点(bpu)
    4、post请求(json)
    3、get请求(url详解)
    2、接口测试(Composer)
    1、Fiddler基础
    常规测试、安全测试、渗透测试-区别
    记录一次python的mysqlclient依赖库报错问题
    airflow当触发具有多层subDAG的任务的时候,出现[Duplicate entry ‘xxxx’ for key dag_id]的错误的问题处理
    Python3并发写文件
    python hash 每次调用结果不一样
  • 原文地址:https://www.cnblogs.com/noblex/p/8151555.html
Copyright © 2011-2022 走看看