Wooden Sticks
Time Limit: 2000/1000 MS (Java/Others)Total Submission(s): 5168
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).
(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).
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
#include <stdio.h>
#include "stdlib.h"
/*
题目的意思是将一系列的(length,weight)进行分组,使得每一组都成序列,
使每组中的length和weight都递增。
本题思路:
1、首先将所有的数进行排序,如果长度相等就按照重量排,从小到大
2、从第一个开始,找出能和第一个放在一个集合的数
比如(4,9), (5,2), (2,1), (3,5),(1,4),
拍完序的结果是(1 4)(2 1)(3 5)(4 9)(5 2),
(1 4)(3 5)(4 9),这可以在一个集合,则总集合数加1,
然后再从头继续找,找到第一个没被加入过的,就找到了(2,1),
然后发现剩下两个都是一个组合,则一共有2组,则需要设置时间两次,
输出为2.
3、贪心算法的思路就是如此,每次从头开始找第一个未被加入集合的项,
用贪心找到所有满足这个集合的。
*/
typedef struct{
int length;
int weight;
}STICK;
void sort_stick(STICK stick[],int n){
for(int i=0;i<n;i++)
for(int j=i;j<n;j++){//注意是i不是1
if(stick[i].length>stick[j].length||
(stick[i].length==stick[j].length&&
stick[i].weight>stick[j].weight)){
int temp=stick[i].length;
stick[i].length=stick[j].length;
stick[j].length=temp;
temp=stick[i].weight;
stick[i].weight=stick[j].weight;
stick[j].weight=temp;
}
}
}
int main()
{
freopen("/Users/qigelaodadehongxiaodi/Desktop/data1.txt", "r", stdin);
//这个不理,是用来方便输入输出的东西,利用文本输入流来读取数据
//提交代码的时候记得注销这条语句
STICK stick[6000];
int flag[6000]={0};//注意数组大小
int n,t;
scanf("%d",&t);
while(t>0){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d %d ",&stick[i].length,&stick[i].weight);
flag[i]=1;
}
sort_stick(stick, n);//按照思路中的2排序
int cnt=0,cntnum=0;
int total=0;
int last_length=0,last_weight=0;
//last_两个代表则上一个,比如(1 4)(2 1)(3 5)(4 9)(5 2)
//找到(1,4),然后变成last_length=1,lats_weight=4
//下一个找到了(3 5),然后就变成了3、5.
while(cnt<n){
while(last_length==0&&last_weight==0){
if(flag[cntnum]!=0){
last_length=stick[cntnum].length;
last_weight=stick[cntnum].weight;
flag[cntnum]=0;
cnt++;
}
cntnum++;
}//这个部分就是没有集合或者上一个集合已经找完全了,开始找下一个集合
//所以会发现last_length、last_weight都是0
if(stick[cntnum].length>=last_length&&stick[cntnum].weight>=last_weight&&flag[cntnum]==1){
flag[cntnum]=0;
last_length=stick[cntnum].length;
last_weight=stick[cntnum].weight;
cntnum++;
cnt++;
}else{
cntnum++;
}
//这部分则是不断的遍历全部,然后把符合条件的放在一个集合
//cnt代表总的被放入的数
//cntnum代表现阶段遍历到的数的下标志
if(cnt==n){
total++;
break;
}//如果最后一个数字都放入了,即cnt==n,我们让总数加1,然后退出
//加入不设置这个退出机制,在样例的第三个钟会少1,
//因为其有三个集合,第三个会在原序列末尾
if(cntnum==n){
cntnum=0;
last_length=0;
last_weight=0;
total++;
}
//如果所有都遍历完了,则继续从头开始遍历,
//即思路中2的思想
}
printf("%d\n",total);
t--;
}
return 0;
}