1051 Wooden Sticks
阿新 • • 發佈:2019-02-11
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; }