不算难题,但是我一开始把一个细节想当然了没仔细看题结果WA了好几次,最后重要发现呵呵。
其实也就是个排序,有点像excel里面可以按第一关键字第二关键字排序什么的,最后数出单调不增交集为空的子列个数就OK,具体步程序里有注解
不好意思,这道题的时候输入格式还是全进全出,下道就好了。
#include
<
iostream
>
using namespace std;
int ttime; // The Min Time
class WoodStick
{
public :
WoodStick()
{
l = 0 ;
w = 0 ;
check = false ;
}
int l;
int w;
bool check;
};
void mysort( int startt, int endd, WoodStick spile[] , bool sortby)
// start,endd为需排序部分的起止数组下标
// spile[]为
// sortby=TRUE表示按l排序,FALSE表示按w排序
{
int i,j;
WoodStick key;
if (sortby)
{
for (j = startt + 1 ;j <= endd;j ++ )
{
key = spile[j];
i = j - 1 ;
while (i >= startt && spile[i].l > key.l)
{
spile[i + 1 ] = spile[i];
i = i - 1 ;
}
spile[i + 1 ] = key;
}
}
else
{
for (j = startt + 1 ;j <= endd;j ++ )
{
key = spile[j];
i = j - 1 ;
while (i >= startt && spile[i].w > key.w)
{
spile[i + 1 ] = spile[i];
i = i - 1 ;
}
spile[i + 1 ] = key;
}
}
}
void GetMinTime( int n, WoodStick spile[])
{
int i,flag,spos;
// 1.首先以l为关键字排序,使用insertion sort
mysort( 1 ,n,spile, true );
// 2.以w为第二关键字在l为第一关键字的前提下排序.
flag = spile[ 1 ].l;
spos = 1 ;
for (i = 2 ;i <= n;i ++ )
{
if (spile[i].l != flag)
{
if (i - 1 - spos > 0 )
{
mysort(spos,i - 1 ,spile, false );
}
spos = i;
flag = spile[i].l;
}
else
{
if (i == n)
{
mysort(spos,n,spile, false );
}
}
}
// 3.在当前已经排好序的组中找出w组单调不减的子列个数
int checked = 0 ,key;
while ( checked != n)
{
key = - 1 ;
for (i = 1 ;i <= n;i ++ )
{
if ( ! spile[i].check)
{
if (key == - 1 )
{
key = spile[i].w;
spile[i].check = true ;
checked ++ ;
}
else
{
if (spile[i].w >= key)
{
key = spile[i].w; // 最终添加了一句,从WA变AC^_^
spile[i].check = true ;
checked ++ ;
}
}
}
}
ttime ++ ;
}
}
int main()
{
int i,j;
int t = 0 ; // The number of test cases (T)
WoodStick pile[ 51 ][ 5001 ];
int pilelen[ 100 ];
// 录入数据
cin >> t;
for (i = 1 ;i <= t;i ++ )
{
cin >> pilelen[i];
for (j = 1 ;j <= pilelen[i];j ++ )
{
cin >> pile[i][j].l;
cin >> pile[i][j].w;
}
}
// 计算W序列
for (i = 1 ;i <= t;i ++ )
{
ttime = 0 ;
GetMinTime(pilelen[i],pile[i]);
cout << ttime << endl;
}
return 0 ;
}
using namespace std;
int ttime; // The Min Time
class WoodStick
{
public :
WoodStick()
{
l = 0 ;
w = 0 ;
check = false ;
}
int l;
int w;
bool check;
};
void mysort( int startt, int endd, WoodStick spile[] , bool sortby)
// start,endd为需排序部分的起止数组下标
// spile[]为
// sortby=TRUE表示按l排序,FALSE表示按w排序
{
int i,j;
WoodStick key;
if (sortby)
{
for (j = startt + 1 ;j <= endd;j ++ )
{
key = spile[j];
i = j - 1 ;
while (i >= startt && spile[i].l > key.l)
{
spile[i + 1 ] = spile[i];
i = i - 1 ;
}
spile[i + 1 ] = key;
}
}
else
{
for (j = startt + 1 ;j <= endd;j ++ )
{
key = spile[j];
i = j - 1 ;
while (i >= startt && spile[i].w > key.w)
{
spile[i + 1 ] = spile[i];
i = i - 1 ;
}
spile[i + 1 ] = key;
}
}
}
void GetMinTime( int n, WoodStick spile[])
{
int i,flag,spos;
// 1.首先以l为关键字排序,使用insertion sort
mysort( 1 ,n,spile, true );
// 2.以w为第二关键字在l为第一关键字的前提下排序.
flag = spile[ 1 ].l;
spos = 1 ;
for (i = 2 ;i <= n;i ++ )
{
if (spile[i].l != flag)
{
if (i - 1 - spos > 0 )
{
mysort(spos,i - 1 ,spile, false );
}
spos = i;
flag = spile[i].l;
}
else
{
if (i == n)
{
mysort(spos,n,spile, false );
}
}
}
// 3.在当前已经排好序的组中找出w组单调不减的子列个数
int checked = 0 ,key;
while ( checked != n)
{
key = - 1 ;
for (i = 1 ;i <= n;i ++ )
{
if ( ! spile[i].check)
{
if (key == - 1 )
{
key = spile[i].w;
spile[i].check = true ;
checked ++ ;
}
else
{
if (spile[i].w >= key)
{
key = spile[i].w; // 最终添加了一句,从WA变AC^_^
spile[i].check = true ;
checked ++ ;
}
}
}
}
ttime ++ ;
}
}
int main()
{
int i,j;
int t = 0 ; // The number of test cases (T)
WoodStick pile[ 51 ][ 5001 ];
int pilelen[ 100 ];
// 录入数据
cin >> t;
for (i = 1 ;i <= t;i ++ )
{
cin >> pilelen[i];
for (j = 1 ;j <= pilelen[i];j ++ )
{
cin >> pile[i][j].l;
cin >> pile[i][j].w;
}
}
// 计算W序列
for (i = 1 ;i <= t;i ++ )
{
ttime = 0 ;
GetMinTime(pilelen[i],pile[i]);
cout << ttime << endl;
}
return 0 ;
}