HDU1051 Wooden Sticks

             Wooden Sticks

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


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

  题义:给定若干(1<= n <=5000)组二维坐标点,凡是满足  "x1<= x2 && y1<= y2"的话那么我们承认这两个坐标是属于同一个集合中。题目要我们求出这些坐标点最少能表示成几个集合。

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

  先将所有的点的信息保存起来,然后选取 x 或者 y 作为对象进行排序,排序中注意如果两个点的 x相同,那么这时候要保持 y有序。这样做的目的是使得所有集合线性的呈现出来,可以理解为经过这样一次排序后,能够每次从前到后找到一个包含点满足题义且最多的点集。不会出现正确分离出来的集合在该排列中有元素是逆序的。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int T;

struct E
{
	int len, wi;
} e[5010];

char hash[5010];

int cmp( const void *a, const void *b )
{
	if( ( ( struct E * )a )-> len!= ( ( struct E * )b )-> len )
	{
	   return ( ( struct E * )a )-> len- ( ( struct E * )b )-> len;
	}
	else
	{
	    return ( ( struct E * )a )-> wi- ( ( struct E * )b )-> wi;
	}
}

int find( int N )
{
	for( int i= 0; i< N; ++i  )
	{
		if( !hash[i] )
		{
			return i;
		}
	}
	return -1;
}

bool ok( int i, int baselen, int basewi )
{
	if( e[i].wi>= basewi )
	{
		return true;
	}
	else
	{
		return false;
	}
}

int main(  )
{
	scanf( "%d", &T );
	while( T-- )
	{
        memset( hash, 0, sizeof( hash ) );
		int N, time= 0;
		scanf( "%d", &N );
		for( int i= 0; i< N; ++i )
		{
			scanf( "%d %d", &e[i].len, &e[i].wi );
		}
 		qsort( e, N, sizeof( e[0] ), cmp );
 		int sta;
		while( 1 )
		{
			sta= find( N );
		//	printf( "sta=%d\n", sta );
			if( sta== -1 )
			{
				break;
			}
			int baselen= e[sta].len, basewi= e[sta].wi;
		//	printf( "blen= %d, bwi= %d\n", baselen, basewi );
			for( int i= sta; i< N; ++i )
			{
				//printf( "blen= %d, bwi= %d\n", baselen, basewi );
				if( !hash[i]&& ok(i, baselen, basewi ) )
				{
					hash[i]= 1;
					//printf( "..%d  ..%d\n", e[i].len, e[i].wi );
					baselen= e[i].len;
					basewi= e[i].wi;
				}
			}
			++time;
 		}
		printf( "%d\n", time );
	}
}

/*

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

*/

原文地址:https://www.cnblogs.com/Lyush/p/2102198.html