ZOJ 3761 Easy billiards[dfs]
2015-01-16 12:58
459 查看
Edward think a game of billiards is too long and boring. So he invented a new game called Easy billiards.
Easy billiards has N balls on a brimless rectangular table in the beginning, and your goal is try to make the number of balls on the table as least as possible by several hit under the following rules:
1: The direction you hit the balls should parallel to the tables border.
2: If ball A crashed into ball B, ball B will moves in the same direction of ball A before the crashing, and ball A will stop in the place of ball B before the crashing.
3: If ball C is moving and there are no balls in front of ball C, it will runs out of the tables border, that means ball C is out of the table.
4: You can choose arbitrary ball on the table to hit, but on a hit, you can't let the ball you choose to hit runs out of the tables border. In another word, a ball could runs out of the table if and only if it was crashed by another ball in a hitting.
Now, Edward wants to know the least number of balls remained on the table after several hits, and how.
N, which means the number of the balls on the table. There are following
N lines, each line contains two integers Xi and Yi, which means the coordinate of ball I. (0<=N<=2000, 0<=Xi,
Yi<=10^8)
you hit. (LEFT,RIGHT,UP,DOWN).
题意:给n个球的坐标,你每次需要选一个球,沿着x轴或y轴去撞别的球,选球停在被撞球位置,被撞球继续前进。选球不能沿着没有球的方向去。最外面的球会被撞出去。问最后最少能剩下多少个球,还要输出选择的方案。
同行或同列的可以连一条边,在同一个连通分量里的最后只剩一个。每次从没被撞掉的点开始搜索,搜索树就是方案。
数据才2000,不用那么麻烦,直接搞就行。
要先输出最后剩下的球数,我在搜索的时候用一个数组把方案保存下来。由于每步操作都少一个球,步数是m,最后的球数是n-m。
Easy billiards has N balls on a brimless rectangular table in the beginning, and your goal is try to make the number of balls on the table as least as possible by several hit under the following rules:
1: The direction you hit the balls should parallel to the tables border.
2: If ball A crashed into ball B, ball B will moves in the same direction of ball A before the crashing, and ball A will stop in the place of ball B before the crashing.
3: If ball C is moving and there are no balls in front of ball C, it will runs out of the tables border, that means ball C is out of the table.
4: You can choose arbitrary ball on the table to hit, but on a hit, you can't let the ball you choose to hit runs out of the tables border. In another word, a ball could runs out of the table if and only if it was crashed by another ball in a hitting.
Now, Edward wants to know the least number of balls remained on the table after several hits, and how.
Input
There are multiple test cases. For each test cases, in the first line, there is an integerN, which means the number of the balls on the table. There are following
N lines, each line contains two integers Xi and Yi, which means the coordinate of ball I. (0<=N<=2000, 0<=Xi,
Yi<=10^8)
Output
For each test cases, you should output the least number of balls on the first line.And you should output several lines to show the order of hits following the first line, each line should contains the coordinate of the ball you choose to hit and the directionyou hit. (LEFT,RIGHT,UP,DOWN).
Sample Input
4 0 0 2 0 4 0 2 2 9 1 1 2 1 3 1 1 2 2 2 3 2 1 3 2 3 3 3
Sample output
1 (2, 2) DOWN (4, 0) LEFT (2, 0) LEFT 1 (1, 3) DOWN (1, 2) DOWN (2, 3) DOWN (2, 2) DOWN (3, 3) DOWN (3, 2) DOWN (3, 1) LEFT (2, 1) LEFT
题意:给n个球的坐标,你每次需要选一个球,沿着x轴或y轴去撞别的球,选球停在被撞球位置,被撞球继续前进。选球不能沿着没有球的方向去。最外面的球会被撞出去。问最后最少能剩下多少个球,还要输出选择的方案。
同行或同列的可以连一条边,在同一个连通分量里的最后只剩一个。每次从没被撞掉的点开始搜索,搜索树就是方案。
数据才2000,不用那么麻烦,直接搞就行。
要先输出最后剩下的球数,我在搜索的时候用一个数组把方案保存下来。由于每步操作都少一个球,步数是m,最后的球数是n-m。
#include<cassert> #include<algorithm> #include<cmath> #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<set> #include<queue> #include<map> using namespace std; #define rep(i,f,t) for(int i = (f), _end = (t); i <= _end; ++i) #define clr(c,x) memset(c,x,sizeof(c)); #define debug(x) cout<<"debug "<<x<<endl; const int INF = 0x3f3f3f3f; typedef long long int64; inline int RD(){ int res; scanf("%d",&res); return res; } #define Rush for(int casn = RD(), cas = 1; cas <= casn; ++cas) //******************************************************************************* const int maxn = 2000+10; const string dirs[4] = { "RIGHT","UP","LEFT","DOWN" }; typedef pair<int,int> Pr; #define x first #define y second typedef vector<int> Vec; bool vis[maxn]; Pr a[maxn]; int n; vector<Pr> out; inline bool jg(int i,int j){ return a[i].x == a[j].x || a[i].y == a[j].y; } void dfs(int i){ vis[i] = 1; rep(j,1,n){ if(vis[j])continue; if(jg(i,j)){ dfs(j); out.push_back(Pr(i,j)); } } } void solve(){ clr(vis,0); rep(i,1,n){ if(vis[i])continue; dfs(i); } } int getdir(const Pr& pr){ int i = pr.first; int j = pr.second; if(a[i].x == a[j].x){ if(a[i].y < a[j].y) return 3; else return 1; }else{ if(a[i].x < a[j].x) return 2; else return 0; } } int main(){ //freopen("3761.in","r",stdin); while(~scanf("%d",&n)){ out.clear(); rep(i,1,n){ scanf("%d%d",&a[i].x, &a[i].y); } solve(); printf("%d\n",n - out.size()); rep(i,0,out.size()-1){ printf("(%d, %d) ",a[out[i].second].x, a[out[i].second].y); int dir = getdir(out[i]); printf("%s\n",dirs[dir].c_str()); } } return 0; }
相关文章推荐
- ZOJ 3761——Easy billiards(DFS,并查集)
- zoj 3761 Easy billiards(建图+贪心+dfs)
- ZOJ 3761 Easy billiards (DFS性质)
- zoj 3761 Easy billiards(dfs搜索树)
- [贪心+dfs] ZOJ 3761 Easy billiards
- zoj 3761 Easy billiards
- ZOJ 3761 Easy billiards(并查集+树遍历)
- 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 月赛E DFS
- Zoj 3761 Easy billiards dfs
- ZOJ 3761 —— Easy billiards(并查集+深搜)
- ZOJ 1708||hdu 1035 Robot Motion (链式前向星,dfs)
- zoj 1456 Minimum Transport Cost(Dijkstra + DFS。。。)
- zoj 1004 , hrbust 1317 Anagrams by Stack【 dfs 】
- zoj 1709 || poj 1562 Oil Deposits(DFS 好吧,目前我就是专门找水题做的。。。)
- zoj 3811 条件下判定某遍历序列的合法性/ 一遍 dfs