题目

题目

 


 

分析

典型搜索,考虑剪枝。

统计一下联通分量。

  • 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;
}

【UVa】11882 Biggest Number(dfs+剪枝)的更多相关文章

  1. UVA - 11882 Biggest Number(dfs+bfs+强剪枝)

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  2. UVA 11882 Biggest Number(搜索+剪枝)

    You have a maze with obstacles and non-zero digits in it: You can start from any square, walk in the ...

  3. 湖南省第六届省赛题 Biggest Number (dfs+bfs,好题)

    Biggest Number 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You have a maze with obstacles and non-zero di ...

  4. UVa 208 消防车(dfs+剪枝)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVA 140 Bandwidth (dfs 剪枝 映射)

    题意: 给定一个n个结点的图G和一个结点的排列, 定义结点i的带宽b(i)为i和相邻结点在排列中的最远距离, 所有b(i)的最大值就是这个图的带宽, 给定G, 求让带宽最小的结点排列. 给定的图 n ...

  6. UVA11882-Biggest Number(DFS+最优化剪枝)

    Problem UVA11882-Biggest Number Accept: 177    Submit: 3117Time Limit: 1000 mSec    Memory Limit : 1 ...

  7. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  8. 湖南省第六届大学生程序设计大赛原题 F Biggest Number (UVA1182)

    Biggest Number http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30851#problem/F 解题思路:DFS(检索)+BF ...

  9. 湖南省第6届程序大赛第6题 Biggest Number

    Problem F Biggest Number You have a maze with obstacles and non-zero digits in it: You can start fro ...

随机推荐

  1. c# 获取随机数字/字符/时间

    using System; using System.Text; namespace HuaTong.General.Utility { /// <summary> /// 随机字符/数字 ...

  2. 《利用Python进行数据分析》笔记---第2章--来自bit.ly的1.usa.gov数据

    写在前面的话: 实例中的所有数据都是在GitHub上下载的,打包下载即可. 地址是:http://github.com/pydata/pydata-book 还有一定要说明的: 我使用的是Python ...

  3. 基于视觉的 SLAM/Visual Odometry (VO) 开源资料、博客和论文列表

    基于视觉的 SLAM/Visual Odometry (VO) 开源资料.博客和论文列表 以下为机器翻译,具体参考原文: https://github.com/tzutalin/awesome-vis ...

  4. MPLS基础一(上)

    在上图中,关于PC-A和PC-B之间互相访问的过程中 1.所有三层网络设备形成源和目的的路由条目 2.PC-A发出报文,source-IP为A,destination-IP为B 3.R1收到报文后,根 ...

  5. c++ 载入内存中dll ,以及内存注入

    用c++ 许多代码都得自己写, 这里是我自己修改的一个内存载入的一个封装库 , c++ 的程序员可以直接拿来用 特点如下: 直接在内存中载入,无磁盘占用 支持加壳保护的dll , 平时用的最多的vmp ...

  6. HDU - 5887:Herbs Gathering (map优化超大背包)

    Collecting one's own plants for use as herbal medicines is perhaps one of the most self-empowering t ...

  7. 实现同时提交多个form(基础方法) 收集(转)

    方法一: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4 ...

  8. 监听器(Listener)学习(二)

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  9. 使用Session防止表单重复提交(不考虑多服务器)

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 原理:  1, ...

  10. Quartz 2D编程指南(7) - 阴影(Shadows)

    阴影是绘制在一个图形对象下的且有一定偏移的图片,它用于模拟光源照射到图形对象上所形成的阴影效果,如果7-1所示.文本也可以有阴影.阴影可以让一幅图像看上去是立体的或者是浮动的. 阴影有三个属性: 1. ...