Wooden Sticks
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 26066 Accepted Submission(s): 10539
Problem Description
There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:
(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup.
You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).
有一堆n个木棍。每个棒的长度和重量是预先知道的。木棒要用木工机械逐一加工。它需要一些时间,称为设置时间,机器准备加工一根棍子。安装时间与清洗操作和更换机器中的工具和形状有关。木工机床的安装时间如下:
(a)第一根木棍的安装时间为1分钟。
(b)在加工长度l和重量w的棒材之后,如果l<=l'和w<=w',机器将不需要长度l'和重量w'的棒材的安装时间。否则,安装需要1分钟。
你要找到最小的设置时间来处理给定的一堆木棒。例如,如果有5根棍子的长度和重量对(4,9)、(5,2)、(2,1)、(3,5)和(1,4),那么最小设置时间应该是2分钟,因为存在一系列对(1,4)、(3,5)、(4,9)、(2,1)、(5,2)。
Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.
Output
The output should contain the minimum setup time in minutes, one per line.
Sample Input
3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1
Sample Output
2
1
3
基本思路:可以将点放在坐标系中观察,将读入的坐标按照坐标排序,排序规则为按照X优先再比较Y,让点符合坐标系特点。
向X轴正方向看,从第一个点(Xi,Yi)开始,观察下一个点(X(i+1),Y(i+1))满足情况,若满足,则从该满足的点(X(i+1),Y(i+1))继续与该点的下一个(X(i+2),Y(i+2))比较,否则选定的第一个点(Xi,Yi)继续与点(X(i+2),Y(i+2))比较并且记录当前位置作为下次搜索的起点,到末尾时便说明没有更大符合条件的,时间+1,并更新下次搜索的起点
例如:
对于题目例子中的(4,9)、(5,2)、(2,1)、(3,5)和(1,4),经过排序后得到的是(1,4)、(2,1),(3,5),(4,9),(5,2)
首先从(1,4)开始向右搜索,发现(2,1)未被计算过,但是不满足情况,那么将该位置记为start(每次搜索前被赋值为n(坐标点的个数)),作为下次搜索的起点,继续向右发现(3,5)满足情况,那么重新将(3,5)作为与下一个比较的点并且标记为已计算,与(4,9)比较,满足情况,则(4,9)与(5,2)比较发现不满足情况,但是已到达尾部,开始下一次搜索,开始位置为start,即(2,1),由于(3,5),(4,9)已经被标记为计算过,将与(5,2)进行匹配,成功,标记为已计算,没有发现匹配不成功的情况,故start位置为n,下次匹配不会进行,即完成全部计算
代码如下
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef struct
{
int x,y; //坐标
int flag; //是否已经被计算的标志,
}lw;
int T,n; //T表示测试次数,n表示一次测试中的数据数
lw a[5001];
inline bool check(lw& a, lw& b) //判断是否满足
{
return a.y<=b.y;
}
inline bool cmp(lw& a,lw& b) //排序,按照先比X后比Y
{
if(a.x==b.x)
return a.y<=b.y;
else
return a.x<b.x;
}
int main()
{
cin>>T;
while(T--)
{
int start,startflag; //start表示当一次搜索完成时下次搜索开始的地方,startflag作为对start进行改变的条件
cin>>n;
for(int i=0;i<n;i++) //读入数据
{
cin>>a[i].x>>a[i].y;
a[i].flag=0;
}
sort(a,a+n,cmp); //排序
int len=0,i=0;
while(i<n)
{
startflag=1; //为1时说明没有记录,为0说明已经记录不用再次记录
start=n; //当一次搜索时全部匹配成功,说明匹配完成,不用继续
for(int j=i+1;j<n;j++)
{
if(!a[j].flag) //当前点没有被计算过
{
if(check(a[i],a[j])) //满足条件
{
i=j;
a[j].flag=1; //标记已被计算过
}
else if(startflag) //不满足情况的点,则下次从该点开始
{
start=j;
startflag=0; //标记,说明下次搜索的起点已经确定,不用再次改变
}
}
}
i=start; //改变下次搜索的起点
len++; //时间加1
}
cout<<len<<endl;
}
return 0;
}