解题思路:
1.按照牛挤奶开始时间进行不递减排序,运用的是折半排序法;
2.从第一头奶牛开始,第一头奶牛肯定放进第一个牛栏里,之后每个奶牛都是与牛栏中开始时间最早的那个相比,如果可以放进去,就放进去啦,如果不能放进去,就重新开一个牛栏。
#include <iostream>
using namespace std;
struct node//存开始时间和结束时间
{
int no;//初始编号
int start;
int end;
int number=0;//牛栏编号
};
struct niulan//存储每个牛栏的结束时间
{
int number;//牛栏编号
int end;
};
void sort(node* a, int len,char c)//如果c='t'按照结束时间排序,升序,如果c='n',按照初始序号进行排序
{
int tno, ts, te, tn;
int low, high, mid;
if (c == 't')
{
for (int i = 1; i < len; i++)
{
if (a[i].start < a[i - 1].start)//需要交换
{
tno = a[i].no;
ts = a[i].start;
te = a[i].end;
tn = a[i].number;
low = 0;
high = i - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (ts < a[mid].start)//在左边寻找
{
high = mid - 1;
}
else
low = mid + 1;
}
for (int j = i - 1; j >= low; j--)
{
a[j + 1].no = a[j].no;
a[j + 1].start = a[j].start;
a[j + 1].end = a[j].end;
a[j + 1].number = a[j].number;
}
a[low].no = tno;
a[low].start = ts;
a[low].end = te;
a[low].number = tn;
}
}
}
else if (c == 'n')
{
for (int i = 1; i < len; i++)
{
if (a[i].no < a[i - 1].no)//需要交换
{
tno = a[i].no;
ts = a[i].start;
te = a[i].end;
tn = a[i].number;
low = 0;
high = i - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (tno < a[mid].no)//在左边寻找
{
high = mid - 1;
}
else
low = mid + 1;
}
for (int j = i - 1; j >= low; j--)
{
a[j + 1].no = a[j].no;
a[j + 1].start = a[j].start;
a[j + 1].end = a[j].end;
a[j + 1].number = a[j].number;
}
a[low].no = tno;
a[low].start = ts;
a[low].end = te;
a[low].number = tn;
}
}
}
}
int min(niulan* a, int len)//找出牛栏中结束时间最早的
{
int p=0;
niulan min;
min.end = a[0].end;
for (int i = 1; i < len; i++)
{
if (min.end > a[i].end)
{
min.end = a[i].end;
p = i;
}
}
return p;
}
int main()
{
node* a = NULL;
int N,n;//N是牛的总数,n是需要的牛栏数
cin >> N;
a = new node[N];//数组a存储每头牛挤奶的开始时间和结束时间
for (int i = 0; i < N; i++)
{
a[i].no = i;
cin >> a[i].start;
cin>> a[i].end;
}
sort(a, N,'t');
a[0].number = 1;
niulan* head = new niulan[N];
head[0].number = 1;
head[0].end = a[0].end;
int number = 1;
for (int i = 1; i < N; i++)
{
int p = min(head, number);
if (a[i].start <= head[p].end)//需要重新分配牛栏
{
head[number].end = a[i].end;
head[number].number = number+1;
number++;
a[i].number = number;
}
else
{
head[p].end = a[i].end;
a[i].number = head[p].number;
}
}
cout << number << endl;
sort(a, N, 'n');
for (int i = 0; i < N; i++)
{
cout << a[i].number << endl;
}
return 0;
}
因为输出的顺序是刚开始输入的顺序,但是在进行排序以后,奶牛的顺序发生了变化,所以要将奶牛写成结构体,存上初始的顺序,还要存上那头牛所在的牛栏编号,当然,考察时间的时候,不能重叠。。。意思就是开始时间为4的不能放进结束时间为4的牛栏里。