1051 Wooden Sticks

Wooden Sticks

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5168    Accepted Submission(s): 2141


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).
 

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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值