想了很久都没有想到。。。看了hzw的题解恍然大悟
居然只是枚举起始位置,然后要取这个位置之前(之后)与它最近的k种珠子的位置的最大值作为这一个起始位置的答案,最后这些答案取min
找最近的珠子:因为题目中已知Ti的珠子位置按升序排序,所以用静态链表把每一种珠子存起来,这样是尾插法,遍历的时候从大到小。同时为了方便,也需要将所有坐标排序,和遍历的顺序一样从大到小枚举起始位置,这样找之前最近比较方便。
get新技能:如果链表中遍历过的东西不要了,可以直接移动头指针,同时能记录位置,和bfs中一样。。。。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n,k,x,y,cnt;
typedef int arr[1000010];
arr num,next,a;
int head[100];
int ans;
bool cal(int x)
{
int tmp=0;
for (int i=1;i<=k;i++)
{
while (num[head[i]]>x)
{
if (next[head[i]]==0) return 0;//不能再找了
head[i]=next[head[i]];//删掉队尾元素,因为已经有序,去掉的可以不要,这样还可以少设变量保存上一次到哪,或者从头再来!!
}
if (num[head[i]]<=x) tmp=max(tmp,x-num[head[i]]);
}
ans=min(ans,tmp);
return 1;
}
int main()
{
cin>>n>>k;
for (int i=1;i<=k;i++)
{
cin>>x;
for (int j=1;j<=x;j++)
{
cin>>y;
num[++cnt]=y;
next[cnt]=head[i];
head[i]=cnt;
a[cnt]=y;
}
}
sort(a+1,a+cnt+1);
ans=0x7fffffff;
for (int i=cnt;i>0;i--)//从后向前找
{
if (a[i]!=a[i+1])
if (!cal(a[i])) break;//有bool值的同时调用
}
cout<<ans;
return 0;
}