湖南省第六届大学生程序设计大赛原题 F Biggest Number (UVA1182)
Biggest Number
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30851#problem/F
解题思路:DFS(检索)+BFS(探路)=强剪枝
一看就知道是搜索题,只是,要是DFS裸搜,真的会超时。时间,非常紧!
做该题的时候,要无时无刻不忘剪枝,抓住一切剪枝的机会,剪吧!
(1)用flag记录当前检索的值与当前已经检索到的最大值的关系,一但有机会,就要剪掉那些检索到的值会比当前最大值要小的“残枝败叶”。
(2)每次DFS检索之前,一定要用BFS“探路”,要是该次检索的值的最大长度小于当前最大值的最大长度,赶紧剪掉。这次搜索到的值不可能比当前最大值大,搜了也白搜,赶紧结束,节约时间。
这里我给出两个代码,一个是参考别人的代码注释来得,一种是用自己的想法从写得到的。
首先,我承认自己做不出来,一直超时。但我是个锲而不舍的孩子,在网上查了资料,弄懂了。代码主人,只在博客中给出代码,没有思路描绘,也没有注释。我做了注释后的成果如下:
1532762 | 20114045007 | F | Accepted | 0 KB | 329 ms | C++ 4.5.3 | 4881 B | 2013-09-03 20:55:11 |
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int x,y;
} queue[1000];
int n,m;
int Max,flag,tatal; //当前检索到的最大值的长度、当前检索值首数字与当前检索到的最大值的首数字的关系、数字总数
char map[20][20]; //输入地图存储
char ans[35],stack[35]; //当前检索到的最大值、当前检索值的情况
int dir[4][2]= {-1,0,0,-1,0,1,1,0}; //四个方向
bool yes(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<m; //该点是否在地图中,是就返回true
}
int bfs(int x,int y) //(x,y)处往后还能搜索到多少位有效数字
{
node t;
char g[20][20];
for(int i=0; i<n; i++)strcpy(g[i],map[i]); //将g中的值赋为map
int head,tail; //队列前后”指针“
head=tail=0; //队列为空
t.x=x,t.y=y; //其实节点,用于入队
queue[tail++]=t; //数组模拟队列
while(head<tail) //队列不为空
{
x=queue[head].x;
y=queue[head++].y; //取出队头元素,队头后移一位
for(int i=0; i<4; i++) //四面查找
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!yes(xx,yy)||g[xx][yy]=='#')continue; //该点不在地图中,该点不可处理【不处理该点】
g[xx][yy]='#'; //要处理该点,标记,预防重处理
t.x=xx,t.y=yy; //记录情况
queue[tail++]=t; //新节点入“队”
}
}
return head; //该次处理的点数
}
void dfs(int x,int y,int cnt) //当前检索点的坐标情况,当前检索到的数的长度
{
if(Max<cnt||(Max==cnt&&flag==1)) //当前检索到的数的长度大于当前检索到的最大的数的总长度“或”长度相等但是当前值首数字比较大
//当前检索到的值必定大于当前检索到的“最大值”【强剪枝2】
{
stack[cnt]=0; //字符串结束标志【别忘了,字符数组没有结束标志会输出错误的】
strcpy(ans,stack); //将当前值赋给”最大值“
Max=cnt; //改变最大值的长度
flag=0; //大小不确定
}
int res=bfs(x,y); //该点后面还能搜索到res个有效数字
if(res+cnt-1<Max||(res+cnt-1==Max&&flag==-1))return; //若该点参与的检索中的有效数字的最大长度小于当前检索到的数字中的最大值的长度
//长度相等,但是该次检索的数字要小【这个数肯定小于当前检索到的最大值】直接结束搜索【强剪枝3】
for(int i=0; i<4; i++) //当前的搜索得到的数肯定会大于当前检索到的最大值,【搜索继续】
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!yes(xx,yy)||map[xx][yy]=='#')continue; //该点不在地图中,或该点不可处理【不作处理】【常规剪枝】
if(flag!=1&&ans[cnt]>map[xx][yy]&&tatal==Max)continue; //当前检索的值不可能大于当前检索到的最大值【强剪枝4】
stack[cnt]=map[xx][yy]; //检索到的数字可用,加入到临时【当前检索值的情况】中
map[xx][yy]='#'; //记得标记哦,检索过的就不要再检索了
if(flag==0) //【】【】大小不确定
{
if(cnt>=Max)flag=1; //长度,当前检索到的比较大
else if(ans[cnt]==stack[cnt])flag=0; //长度想相同就比首字母 【大小不确定】
else if(ans[cnt]<stack[cnt])flag=1; //当前检索到的i较大
else flag=-1; //当前检索到的比较小
dfs(xx,yy,cnt+1); //长度加1
flag=0;//【大小不确定】
}
else dfs(xx,yy,cnt+1); //若大小确定,继续检索
map[xx][yy]=stack[cnt]; //搜索归来,抹去标记
}
}
int main()
{
while(scanf("%d%d",&n,&m)&&n+m)
{
tatal=0;
for(int i=0; i<n; i++)
{
scanf("%s",map+i);
for(int j=0; j<m; j++)
{
if(map[i][j]!='#')tatal++;
}
}
Max=1;
memset(ans,0,sizeof(ans));
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(map[i][j]=='#')continue;
if(Max==tatal&&ans[0]>map[i][j])continue; //当前检索到的最大值,长度已达到最长&&开头数字比当前检索数字大
//以当前数字开头检索到的最大值肯定小于当前检索到的最大值【强剪枝1】
stack[0]=map[i][j];
map[i][j]='#'; //访问标记
if(ans[0]==stack[0])flag=0;//大小不确定
else if(ans[0]<stack[0])flag=1; //大于
else flag=-1; //小于
dfs(i,j,1);
map[i][j]=stack[0]; //搜索归来,抹掉标记
}
}
printf("%s\n",ans); //输出最终答案
}
return 0;
}
原码转自:http://blog.csdn.net/andring/article/details/7376129
本人代码:更新中。。。
湖南省第六届大学生程序设计大赛原题 F Biggest Number (UVA1182)的更多相关文章
- 湖南省第八届大学生程序设计大赛原题 D - 平方根大搜索 UVA 12505 - Searching in sqrt(n)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30746#problem/D D - 平方根大搜索 UVA12505 - Searchin ...
- 湖南生第八届大学生程序设计大赛原题 C-Updating a Dictionary(UVA12504 - Updating a Dictionary)
UVA12504 - Updating a Dictionary 给出两个字符串,以相同的格式表示原字典和更新后的字典.要求找出新字典和旧字典的不同,以规定的格式输出. 算法操作: (1)处理旧字典, ...
- NYOJ-712 探寻宝藏(第六届河南省程序设计大赛)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫 ...
- 河南省第六届ACM程序设计大赛
C: 最舒适的路线 (并查集) #include<cstdio> #include<cstring> #include<iostream> #include< ...
- River Crossing---河南省第六届大学生程序设计竞赛
题目描述 Afandi is herding N sheep across the expanses of grassland when he finds himself blocked by a ...
- Contest - 中南大学第六届大学生程序设计竞赛(Semilive)
题1:1160十进制-十六进制 注意他给的数据范围 2^31,int是 2^31-1 #include<iostream> using namespace std; int main() ...
- 校第十六届大学生程序设计竞赛暨2016省赛集训队选拔赛(Problem E)
Problem E Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- ZOJ 4100 浙江省第16届大学生程序设计竞赛 A题 Vertices in the Pocket 线段树+并查集
正赛的时候完全没看这个题,事后winterzz告诉我他想出来的解法. 首先题意是给出n个点,m次操作. 操作有一种是连接两个点,另一种是求此时再为这个图连k条边,最少和最多能有几个联通块. 最少的求法 ...
- ZOJ 4103 浙江省第16届大学生程序设计竞赛 D题 Traveler 构造
这个题,正赛的时候也没有过,不过其实已经有了正确的解法,可惜时间不多了,就没有去尝试. 题意是有n个点,i点能通向i-1,然后i和i*2.i*2+1互通. 请你构造一种路径从1能走完所有点,并且不重复 ...
随机推荐
- Mysql数据库里面的String类型依照数字来排序以及按时间排序的sql语句
今天做项目的时候,遇到个小小的问题,在数据库中查询的时候,要用String类型的ID进行一下排序!(注:ID字段为 varchar 类型) 解决的方法: 如: SELECT * FROM Stude ...
- extJs项目实战
extjs是因为在公司用到一次,也是公司唯一一个extjs的项目,当时拿到这个需求的时候,我有点懵逼,这他妈的什么鬼,参加工作两年不到的纯小白,没办法,这是工作,必须要完成的.硬着头皮做吧,好在最后弄 ...
- Google map实现类似Google earth的图标展开功能
前言 在Google map的开发时,如果有多个图标重叠在一起,这时下面的图标就点击不到.而在Google Earth中,鼠标一移到上面就会自动弹开,这对于用户而言是十分人性化的一个功能.如下是在Go ...
- java 上传文件
public static boolean upload(File file, String savepath, String loginNo, String filename) { boolean ...
- jquery实现复选框全选反选
实现原理: 给所有的复选框取相同的名字,当点击全选的时候把chenked属性全部设置为true;当点击全不选的时候把checked属性设置为false; 源代码如下: html代码: <form ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- IE6 png 透明 (三种解决方法)(转来的哦)
FF和IE7已经直接支持透明的png图了,下面这个主要是解决IE6下透明PNG图片有灰底的 ====================================================== ...
- Flask学习记录之Flask-Moment
Moment.js 是一个简单易用的轻量级JavaScript日期处理类库,提供了日期格式化.日期解析等功能.它支持在浏览器和NodeJS两种环境中运行.此类库能够 将给定的任意日期转换成多种不同的格 ...
- A Simple Math Problem(HDU 1757 构造矩阵)
If x < 10 f(x) = x.If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-1 ...
- sql基础复习
--.while循环 declare @sum int declare @i int ) begin set @sum =@sum+@i ) print @i end print @sum --.go ...