ZOJ-1025-Wooden Sticks

本文介绍了一个涉及排序算法的具体应用场景,通过实现类似Excel的多关键字排序功能,并计算特定条件下子序列的数量,展示了排序算法的实际运用技巧。

不算难题,但是我一开始把一个细节想当然了没仔细看题结果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;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值