Título: cobertura intervalo
significado de las preguntas: Sí n (1 <= n <= 25 000) un intervalo cerrado [ai, bi] línea de números, seleccione el menor número de secciones cubren un segmento de línea especificado [1, t] (1 < = t <= 1.000.000).
Cubriendo el punto entera, es decir, (1,2) + (3,4) puede cubrir (1,4).
La salida imposible -1
Entrada:
Primera línea: N T y la
segunda fila N + 1 a la fila: cada línea de un intervalo cerrado.
Salida:
el número de secciones seleccionadas, las salidas imposibles -1
La resolución de problemas ideas: problema de cobertura intervalo de resolver codiciosos; Volver la cabeza hasta la cola, es decir, el extremo izquierdo de la línea es de menos de 1 punto a lo dejó en 1 (si el punto extremo derecho es inferior a 1, no afecta); a continuación, ordenados en el punto de la línea ascendente a la izquierda . A continuación, el momento adecuado para tomar el máximo de puntos (los mismos que si el punto de la izquierda, a continuación), si es distinto del punto de la izquierda, para llevar a cabo un juez especial, aspecto en el siguiente punto no se deja en el valor de 1 (más uno deberán tener consejos anteriores), si en el caso, para detener la salida -1; si no, el punto que desea sobrescribir la línea de fondo a la izquierda en el punto extremo derecho del segmento de línea que su seleccionado en ese momento, y luego continuar con cortar cabezas, hasta que los resultados obtenidos;
entonces este método ¿por qué se puede? Dejamos la mayoría de los segmentos de cubierta, por ejemplo, que hemos elegido es el punto izquierdo inferior o igual valor en el punto extremo derecho de la línea 1 menos 1 el más grande, y si usted no elige esto, entonces podemos elegir sólo uno más pequeño que esto, por lo que va a ser algo más que el resto de la gama, su situación no está mejorando aún peor, o elegir continuar este problema en la línea frente a la misma después de que finalice la selección de la extrema izquierda. Desde aquí podemos ver que la codicia debe ser óptima.
Temas similares (el mal de la vaca)
lugar engañosa: Por favor nota que el mencionado anteriormente que abarca todo el punto, no tengo esta información cuando se trata, pensaron que era un segmento de línea cubierto, y luego una locura blanco. . . Así que asegúrese de que añade uno!
código:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
bool cmp(pair<int,int> a,pair<int,int> b)
{
return a.first<b.first;
}
int main()
{
int n,t,x,y;
vector<pair<int,int> > h;
while(scanf("%d%d",&n,&t)!=EOF)
{
int total=1,flag=-1,b=1;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
if(x>y)//由于被坑的有点厉害,就谨慎了一点
{
swap(x,y);
}
if(x<1){x=1;}//裁剪
if(y>t){y=t;}
h.push_back(make_pair(x,y));
}
if(n==0||t<1)//谨慎
{
printf("-1\n");
h.clear();
continue;
}
sort(h.begin(),h.end(),cmp);//排序
if(h[0].first>1)//特判第一个
{
printf("-1\n");
h.clear();
continue;
}
for(int i=0;i<n;i++)//进行贪心
{
if(h[i].first>b)//如果当前线段左端点数值和b不同,说明左端点为b的线段已经筛选完了
{
if(h[i].first>flag+1)//记住,一定要加个1!!!
{
printf("-1\n");
break;
}
total++;//所选的线段数加1
for(int j=i;j<n;j++)//把左端点进行变更,并进行裁剪
{
if(h[j].first<flag+1)
{
h[j].first=flag+1;
}else
{
break;
}
}
b=flag+1;//变更左端点
}
flag=max(flag,h[i].second);//求个右端点最大的
if(flag==t)//判断一下
{
printf("%d\n",total);
break;
}
if(i==n-1)//扫完了还没成功,就说明失败了
{
printf("-1\n");
}
}
h.clear();
}
}