【topcoder第二弹】SRM 526 Div.1 DucksAlignment

Problem Statement

 Mr. Dengklek has a rectangular farm conveniently divided into a grid of unit squares. At this moment, each unit square contains at most one duck. Moreover, each row and column of the farm also contains at most one duck. You are given a String[] grid. The j-th character of the i-th element of grid will be 'o' if there is exactly one duck in square (i, j), i.e., row i column j, or '.' if there is no duck in that square.

Today, Mr. Dengklek wants to align the ducks so that the ducks form a contiguous line. More precisely, assume that there are N ducks on the farm. After the alignment, the ducks must either occupy N contiguous squares in some row or N contiguous squares in some column. To accomplish that, he will move the ducks one at a time. To move a duck in square (a, b) to another empty square (c, d), he needs |a-c| + |b-d| seconds, where |x| denotes the absolute value of x. Mr. Dengklek can always move any duck to any empty square he desires - the other ducks are not obstacles.

Return the minimum time in seconds Mr. Dengklek needs to align the ducks. Note that restrictions imposed on the initial placement of ducks guarantee that a proper alignment is always possible.

Definition

 
Class:DucksAlignment
Method:minimumTime
Parameters:String[]
Returns:int
Method signature:int minimumTime(String[] grid)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):64

Constraints

-grid will contain between 1 and 50 elements, inclusive.
-Each element of grid will contain between 1 and 50 characters, inclusive.
-All elements of grid will contain the same number of characters.
-Each character of grid will be either 'o' or '.'.
-Each row in grid will contain at most one character 'o'.
-Each column in grid will contain at most one character 'o'.
-grid will contain at least one character 'o'.

Examples


0)

{".o",
 "o."}
Returns: 1
Move either duck to an adjacent empty square.


1)

{".o...",
 "..o..",
 "....o"}
Returns: 3
One of the solutions is: move the the duck in the first row one square to the right, and then move the duck in the last row two squares to the left.


2)

{"o..........",
 "..o........",
 ".......o...",
 "...........",
 "...........",
 "...........",
 "........o..",
 "..........."}
Returns: 16
Align all ducks in the second row.


3)

{".........",
 "....o....",
 "........."}
Returns: 0

4)

{"...o..........................",
 "............................o.",
 ".o............................",
 "............o.................",
 ".................o............",
 "......................o.......",
 "......o.......................",
 "....o.........................",
 "...............o..............",
 ".......................o......",
 "...........................o..",
 ".......o......................"}
Returns: 99


This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.


题目大意:给鸭子排队,给出一张图,图上有一些鸭子('o')。保证每一行最多有一只;每一列最多有一只。现在要把这些鸭子排成一横行或一竖列,一只鸭子移动一格需要耗费一单位时间,每次只能有一只鸭子移动。问最短多长时间能排完。

题目分析:我是用贪心做的这道题,找最靠近全图中心的一只鸭子,让它当标准点。横竖一样(曼哈顿距离)……然后就剩下计数了。

code:

public class DucksAlignment{
	public int minimumTime(String[]grid){
		//x数组和y数组分别记录所有点的坐标
		//mCount记录点的总数(有点行可能没有点)
		//ans记录答案,signedP记下标准点(距离中心最近的点)
		//cx,cy分别记录标准点的横纵坐标
		int x[],y[],mCount=0,ans=0,signedP=0,cx,cy;
		x=new int[grid.length];
		y=new int[grid.length];
		cx=grid[0].length()/2;
		cy=grid.length/2;
		//其实这里应该取grid.length和grid[任一].size()中小的那个,大点也无所谓了
		for(int i=0;i<grid.length;i++){
			x[mCount]=grid[i].indexOf("o");
			if(x[mCount]!=-1){
				y[mCount++]=i;
				if(douPoiDis(x[mCount-1],y[mCount-1],cx,cy)<douPoiDis(x[signedP],y[signedP],cx,cy)){
					signedP=mCount-1;
				}
			}
		}
		for(int i=0;i<mCount;i++)//最外层循环,判断哪个为标准点
			ans+=douPoiDis(x[i],y[i],x[signedP],y[signedP])-Math.abs(i-signedP);
		//每个点可以少移动(距离标记点的值)次
		return ans;
	}
	public static int douPoiDis(int x1,int y1,int x2,int y2){
		return Math.abs(x1-x2)+Math.abs(y2-y1);
	}
}

PS:总感觉有不对的地方,后来一想,应该是这样:根据(图中最上方一只鸭子所在行作第一行…二…三…四…)重构子图,在子图的基础上实现以上算法,才是王道。我这么写也对了,应该是侥幸吧。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值