Campamento de verano 2 9

Intervalo de W pequeño

** El maestro da pequeños intervalos W n con extremos cerrados en el eje x. Deje que la pequeña W elimine la menor cantidad posible de intervalos cerrados para que los intervalos cerrados restantes no se crucen.
«Tarea de programación:
Dados n intervalos cerrados, programe y calcule el número mínimo de intervalos cerrados eliminados.
**

Ordene según el punto derecho del intervalo y luego agregue el nodo izquierdo para ver si se puede agregar, codicioso

using namespace std;
inline int read()
{
    int f=1,res=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
    return res*f;
}
int n,ans;
struct node
{
    int x;
    int y;
} a[10010];
inline bool cmp(node x,node y)//规则
{
    if(x.y==y.y)return x.x<y.x;
    return x.y<y.y;
}
int r=-0x7fffffff;
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
       a[i].x=read();
       a[i].y=read();
       if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        if(a[i].x>r)r=a[i].y;
        else ans++;
    }
    cout<<ans;
    return 0;
}


Little W en la selección de asientos

Inserte la descripción de la imagen aquí
1. Para un pasajero, si es el último en elegir un asiento, asumiendo que se cruza con el itinerario de C pasajeros, entonces se requieren al menos C + 1 asientos. Luego enumere a cada pasajero para averiguar cuántos se cruza con él y simplemente tome el valor máximo requerido.
2. Puede ser similar a agregar valor a un intervalo, si no hay valor, entonces nadie

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    
    
    int f=1,res=0;char ch=getchar();
    while(!isdigit(ch)){
    
    if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){
    
    res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
    return res*f;
}
int n,sum[200010],xc[200010],sc[200010],maxx;
struct node
{
    
    
    int l;
    int r;
}a[200010];
inline bool cmp(node x,node y)
{
    
    
    if(x.l==y.l)return x.r>y.r;
    return x.l<y.l;
}
inline void problem1()
{
    
       
    int ans=0;
   for(int i=1;i<=maxx;i++)xc[i]+=xc[i-1];
   for(int i=maxx;i>=1;i--)sc[i]+=sc[i+1];
   for(int i=1;i<=n;++i) 
   ans=max(ans,n-(xc[a[i].l]+sc[a[i].r]));
   cout<<ans<<' ';
}
inline void problem2()
{
    
    
    int ans=0;
    for(int i=1;i<=maxx;i++)sum[i]+=sum[i-1],ans=max(ans,sum[i]);
    cout<<ans;
}
int main()
{
    
    
    n=read();
    for(int i=1;i<=n;i++)
    {
    
    
        a[i].l=read();
        a[i].r=read();
        sum[a[i].l]++;
        sum[a[i].r]--;
        xc[a[i].r]++;
        sc[a[i].l]++;
        maxx=max(maxx,a[i].r);
    }
    problem1();
    problem2();
    return 0;
}


Montaña rusa de fantasía

Inserte la descripción de la imagen aquí
Encuentra el lado más corto conectado a 1 para hacer un anillo. Si la distancia es mayor que el tamaño del anillo, entonces no es más que caminar sobre el anillo varias veces.

//提供hzj的标程
#include <iostream> 
#include <cstdlib>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>//d:与起点相连的边上最短边长度*2,即为起点直连的1个最小的环 
//此题主要在于,对于长度为p的1到n的路径,若其存在从1到n的一条路径l,l的长度%d=p%d且l的长度<=p 
using namespace std;
//因为只要有这样的l,p即为先在起点连接的最小的环绕((p-l)/d)圈再走l那条路径 
typedef pair<int,int> PR;
#define mp make_pair
#define fi first
#define sc second

const int N=10010,M=20010,inf=0x3f3f3f3f;
int n,m,Q,p,t,Head[N],ver[M],cost[M],Next[M],tot=1,mi=100,f[N][110],d;
bool vis[N][110];//f[i][j]:由起点1开始,到i点,长度%d==j的路径中,最短的路径的长度 
queue <PR> q;

void re(int &x)
{
    
    
    x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
}

inline void add(int x,int y,int z)
{
    
    
    ver[++tot]=y; cost[tot]=z; Next[tot]=Head[x]; Head[x]=tot;
}

void spfa(int mo)
{
    
    //不需要担心路径过程中更小的环,spfa过程中会一圈一圈套出来,最后求出的f[i][j]定为到i,距离%d为j的最短距离 
    int i,x,disx,y,disy;
    memset(f,0x3f,sizeof(f));//初始化为最大值,以便后期更新 
    q.push(mp(1,0)); vis[1][0]=1; f[1][0]=0;//到点1的距离当然为0,%d也为0,入队 
    while(!q.empty())
    {
    
    
        x=q.front().fi; disx=q.front().sc; q.pop();//取出队首,x为当前点,disx为当前到当前点的最小距离%d的值 
        vis[x][disx]=0;//退队 
		for(i=Head[x];i;i=Next[i])
        {
    
    
            y=ver[i]; disy=(disx+cost[i])%mo;//y为下一点,disy为由当前点到y算出的1到y的距离%d的值 
            if(f[x][disx]+cost[i]<f[y][disy])//松弛操作 
            {
    
    
                f[y][disy]=f[x][disx]+cost[i];
                if(!vis[y][disy])//从1到y,路径长%d为disy的情况,没有再队列中 
                {
    
    
                    vis[y][disy]=1;
                    q.push(mp(y,disy));//入队 
                }
            }
        }
        
    }
}

int main()
{
    
    
    int u,v,w,i;
    re(n); re(m);
    for(i=1;i<=m;i++)
    {
    
    
        re(u); re(v); re(w);
        add(u,v,w);
        add(v,u,w);//无向边建双向 
    }
    d=inf;
    for(i=Head[1];i;i=Next[i]) d=min(d,cost[i]);//找到起点1的出边中最短的 
    re(Q);
    if(d==inf)//如果起点1压根就没有出边,那肯定都不行 
    {
    
    
        while(Q--) printf("AKTang!\n");
        return 0;
    }
    d*=2;//把最短的出边*2,变成最小的环 
    spfa(d);//以最小的环为模数进行spfa 
    while(Q--)
    {
    
    
        re(p);
        if(f[n][p%d]<=p) printf("AWaDa!\n");//如果可以通过绕d跑几圈,加上一个路径到n,总长为p,存在总长为p的路径 
        else printf("AKTang!\n");//否则不存在 
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/yhhy666/article/details/108277069
Recomendado
Clasificación