[贪心+dfs] ZOJ 3761 Easy billiards
来源:互联网 发布:并发编程网 lock 编辑:程序博客网 时间:2024/05/21 17:11
题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3761
题目意思:
二维矩阵上有n个球,沿水平或竖直打球,当A球与B球碰撞时,A球停在B球的位置,B求以A球的运动方向继续运动,球出边界后就消失了。打第一个球时,该球沿运动方向必须至少一个球才能打。求桌子上剩下的最少的球的个数,输出任意一种打球方案。
解题思路:
贪心+dfs
如果A能打,打了过后等价于A去掉,其他球的位置不变
首先预处理出每个点在4个方向上的最近的点,dfs,只要四个方向上存在一个球,就从该球开始继续往下搜,直到四个方向不存在球为止,搜完后回溯时记录方案。
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<vector>#define Maxn 2200#include<cstring>#define INF 0x3f3f3f3fusing namespace std;struct Point{ int x,y;}pp[Maxn];struct Inf{ int x,y; int dd;}ans[Maxn];vector<int>myv[Maxn][5];//记录i点4个方向上最近的球的序号bool vis[Maxn];int n,dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}},cnt;bool hav[5];void dfs(int cur,int dd){ for(int k=1;k<=4;k++) { for(int p=0;p<myv[cur][k].size();p++) { if(vis[myv[cur][k][p]]) continue; vis[myv[cur][k][p]]=true; dfs(myv[cur][k][p],k); } } ++cnt; ans[cnt].x=pp[cur].x; ans[cnt].y=pp[cur].y; ans[cnt].dd=dd; //记录打球的方案 倒着输出}int main(){ //printf("%d\n",INF); while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d%d",&pp[i].x,&pp[i].y); for(int j=1;j<=4;j++) myv[i][j].clear(); } for(int i=1;i<=n;i++) { int Max[5]; int temp[5]; for(int i=1;i<=4;i++) Max[i]=INF; for(int j=1;j<=n;j++) { if(i==j) continue; if(pp[j].x==pp[i].x) //上1 右2 下3 左4 { if(pp[j].y>pp[i].y&&pp[j].y<Max[1]) { Max[1]=pp[j].y; //向上的最近的球 temp[1]=j; } if(pp[j].y<pp[i].y&&pp[j].y<Max[3]) { Max[3]=pp[j].y; //向下的最近的球 temp[3]=j; } } if(pp[j].y==pp[i].y) { if(pp[j].x>pp[i].x&&pp[j].x<Max[2]) { Max[2]=pp[j].x; //向右的最近的求 temp[2]=j; } if(pp[j].x<pp[i].x&&pp[j].x<Max[4]) { Max[4]=pp[j].x; //向左的最近的球 temp[4]=j; } } } for(int k=1;k<=4;k++) { if(Max[k]!=INF) myv[i][k].push_back(temp[k]); } } memset(vis,0,sizeof(vis)); int an=0; cnt=0; for(int i=1;i<=n;i++) { if(vis[i]) continue; an++; //每一块剩下一个球 vis[i]=true; for(int k=1;k<=4;k++) { for(int p=0;p<myv[i][k].size();p++) { if(!vis[myv[i][k][p]]) { vis[myv[i][k][p]]=true; dfs(myv[i][k][p],k); } } } } printf("%d\n",an); for(int i=1;i<=cnt;i++) { printf("(%d, %d) ",ans[i].x,ans[i].y); switch(ans[i].dd) { case 1:printf("DOWN\n");break; case 2:printf("LEFT\n");break; case 3:printf("UP\n");break; case 4:printf("RIGHT\n");break; } } } return 0;}/*20 01 140 01 01 12 260 01 01 12 23 33 2*/
0 0
- zoj 3761 Easy billiards(建图+贪心+dfs)
- [贪心+dfs] ZOJ 3761 Easy billiards
- ZOJ 3761 Easy billiards[dfs]
- Zoj 3761 Easy billiards dfs
- zoj 3761 Easy billiards(dfs搜索树)
- ZOJ 3761 Easy billiards (DFS性质)
- zoj 3761 Easy billiards
- zoj 3761 Easy billiards
- zoj 3761 Easy billiards 并查集+dfs
- Easy billiards (zoj 3761 并查集+DFS)
- zoj 3761 Easy billiards 乱搞
- ZOJ 3761——Easy billiards(DFS,并查集)
- ZOJ 3761 Easy billiards(并查集+树遍历)
- Easy billiards
- ZOJ 3761 —— Easy billiards(并查集+深搜)
- ZOJ 3761 —— Easy billiards(并查集+深搜)
- ZOJ 3764 Easy billiards 月赛E题
- zoj3761 Easy billiards
- puma 配置,启动脚本
- ios中单例的两种写法~~~
- 阳光梦:Android 核心分析 之八------Android 启动过程详解
- 巴氏系数的最大化 与 Mean Shift 漂移的关系
- poj1611The Suspects
- [贪心+dfs] ZOJ 3761 Easy billiards
- apache
- 线程池Executor与ExecutorService
- VC字符串根据指定字符分割成CStringArray
- UIButton 按钮控件-IOS开发
- Linux CentOS 浏览器乱码,支持中文解决;以及中文输入法的安装
- redis根据前缀删除数据
- 情景模式的界面设计
- ASP.NET FormView中编辑时的RadioButtonList控件报错,找不到匹配的Value