描述
C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否则需要消耗一个单位的时间。因为急着去约会,C小加想在最短的时间内把木棒处理完,你能告诉他应该怎样做吗?
输入
第一行是一个整数T
(1<T<1500)
,表示输入数据一共有T组。
每组测试数据的第一行是一个整数N(1<=N<=5000),表示有N个木棒。接下来的一行分别输入N个木棒的L,
W(0<L,W<=10000)
,用一个空格隔开,分别表示木棒的长度和质量。
输出
处理这些木棒的最短时间。
样例输入
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
样例输出
2
1
3
思路:
a[i]包括3个属性,长度l,宽度w,和 flag(0表示未被访问过,1表示已经访问过)
先按照长度将木棍a[1~n]进行从小到大的排序。
之后,一开始的想法是,排完序之后,再走以下步骤:
1. num=0 ; left=1 ; right = N;
2. 从所有[left , right ]范围内的所有a[i].flag==0的木棍中,选择w最小的木棍
3. 将这个木棍a[i].flag=1 , num++;
4. 令left=i+1 ,重复2 ,做到到顶,再继续第5步
5. 从i=1开始遍历,寻找第一个a[i].flag==0的那个i ,令left=i ,重复第2步。直到所有的元素的flag都为1。
int main()
{
对a.l进行排序;
while(还有a[i].flag==0)
{
从i=1开始遍历,寻找第一个a[i].flag==0的那个i ,令left=i;
num++;
for(i<=N)
{
从所有[left , right ]范围内的所有a[i].flag==0的木棍中,选择w最小的木棍;
a[i].flag=1 ;
left=i+1;
}
}
print(num) ;
}
这个过程,写起来太复杂,提过后, 直接显示超时了。
于是就去寻找别人的代码,发现,其实根本就不比一定要从最小的开始。
从1开始选择第一个a.flag==0的a[i]。从他开始,发现后面第一个比他的w大的元素就行,不必是最小的。
1. 对a.L进行排序. 令num=0; s=1;
2. 从i=1开始选择第一个a[i].flag==0的a[i]。如果所有的flag==1,结束循环,否则进行步骤3
3. num++ ; b=i ; j=i+1;
4. 如果s[j].w>=s[b].w 且 s[j].flag=0, 那么令s[j].flag=1 , b=j ; j++;否则 只有 j++; 不断重复第4步,直到j>=N
5. 步骤4结束后,调到第2步循环
int main()
{
对a.l进行排序;
while(还有a[i].flag==0)
{
从i=1开始遍历,寻找第一个a[i].flag==0的那个i ,令left=i;
num++;
j=i+1;
s=i;
for(j<=N)
{
从i 开始找到第一个 j 有a[i].flag==0 且a[j].w>a[i].w
a[j].flag=1 ;
s=j;
j++;
}
}
print(num) ;
}
- c++排序确实方便
- 即使a.L是有序的,但是当L相同时,这时就要求具有相同L的元素,他们的w也是有序的。这就是为什么,有的人说,对L排序AC了,但是对W排序就出错的原因。但是用c语言快排时不能够一次实现的。而在c++中,直接sort(… , … , CMP).再写个简单的CMP函数就完了
参考博客 :http://blog.csdn.net/u013806814/article/details/38827077
#include<stdio.h>
#include<malloc.h>
struct data{
int l;
int w;
int flag; //0表示未被访问,1表示已经访问
};
void kuaipai(struct data* a,int l,int r);
int smallest(struct data* a,int l,int r);
void kuaipai2(int* a,int l,int r);
int main()
{
int T=0,N=0;
int i=0,j=0,k=0,s=0;
int L=0,W=0;
int num=0;
int b=1,c=1;
int* r=0;
struct data* a=0;
scanf("%d",&T);
for(i=1;i<=T;i++)
{
scanf("%d",&N);
a=(struct data*)malloc(sizeof(struct data)*(N+1));
r=(int*)malloc(sizeof(int)*(N+1));
for(j=1;j<=N;j++)
{
scanf("%d%d",&a[j].l,&a[j].w);
a[j].flag=0;
}
kuaipai(a,1,N);//按照a[i].l从大到小排序
//for(j=1;j<=N;j++)
// {
// printf("%d %d %d\n",a[j].l,a[j].w,a[j].flag);
// }
b=1;
r[b]=a[b].w;
r[0]=1;
c=2;
for(j=2;j<=N;j++)
{
if(a[j].l==a[b].l)
{
r[c]=a[j].w;
c++;
r[0]++;
if(j!=N)
{
continue;
}
}
kuaipai2(r,1,r[0]);
for(c=1;c<=r[0];c++)
{
a[b+c-1].w=r[c];
// printf("%d\n",a[b+c-1].w);
}
b=j;
c=1;
r[c]=a[b].w;
c++;
r[0]=1;
}
//for(j=1;j<=N;j++)
//{
// printf("%d %d %d\n",a[j].l,a[j].w,a[j].flag);
// }
a[0].flag=N;
num=1;
while(1)
{
for(k=1;k<=N;k++)
{
if(a[k].flag==0)
{
a[k].flag=1;
// printf("%d %d %d\n",a[k].l,a[k].w,a[k].flag);
num++;
break;
}
}
if(k>=N)
{
break;
}
s=k;
for(k=k+1;k<=N;k++)
{
if(a[k].flag==0 && a[k].w>=a[s].w)
{
a[k].flag=1;
// printf("%d %d %d\n",a[k].l,a[k].w,a[k].flag);
s=k;
}
}
}
printf("%d\n",num-1);
}
return 0;
}
void kuaipai(struct data* a,int l,int r)
{
int i=l,j=l;
int k=a[r].l;
int x=0,y=0;
if(l>=r)
return;
for(i=l;i<=r-1;i++)
{
if(a[i].l<k)
{
x=a[i].l;
y=a[i].w;
a[i].l=a[j].l;
a[i].w=a[j].w;
a[j].l=x;
a[j].w=y;
j++;
}
}
x=a[r].l;
y=a[r].w;
a[r].l=a[j].l;
a[r].w=a[j].w;
a[j].l=x;
a[j].w=y;
kuaipai(a,l,j-1);
kuaipai(a,j+1,r);
return;
}
void kuaipai2(int* a,int l,int r)
{
int i=l,j=l;
int k=a[r];
int y=0;
if(l>=r)
return;
for(i=l;i<=r-1;i++)
{
if(a[i]<k)
{
y=a[i];
a[i]=a[j];
a[j]=y;
j++;
}
}
y=a[r];
a[r]=a[j];
a[j]=y;
kuaipai2(a,l,j-1);
kuaipai2(a,j+1,r);
return;
}