• Codeforces 1041C Coffee Break


    比赛时候简直脑抽......以为是个链表写了一个多小时最后跑的还没暴力模拟快

    题意(精简):

    给定一个有 $ n $ 个数的数组,将其分成尽量少的若干组,使得每一组中任意两个数字的差不小于给定的常数 $ d $ 。

    题解:

    用结构体存储标号,数值和答案,方便排序处理和输出。

    使用单调队列维护,队列中的数字为「某个组上一个数字」,队首即为「所有组上一个数字中最小的那个」。

    首先按数值由小到大排一下序,然后将第一个数字push进队列,开一组。

    然后,对于接下来的每个数,有两个选择:继承到某个组的后面,或者为自己新开一个组。

    检查队首:

    ·如果队首与当前数字的差值大于 $ d $ ,就把当前的数字继承到「队首数字所在的组」,将队首pop掉,将当前数字push进队尾。

    ·如果队首与当前数字的差值小于等于 $ d $ ,那么由于是单调队列,之后的元素只会更大,一定不会满足。

    此时只能选择为这个数字新开一组,并将其push进队尾。

    最后,输出总共开了多少组,然后将所有结构体按输入的顺序重新排好,依次输出所属的组号。

    代码如下:

    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n,m,d;
    int cnt=0;//组号 
    struct cof{
    	int in,time,bl;//in:输入顺序 bl:belong,属于哪一组 
    	cof(int in=0,int time=0,int bl=0):
    		in(in),time(time),bl(bl){
    			
    		}
    };
    cof a[200050];
    bool cmp1(const cof x,const cof y){
    	return x.time<y.time;
    }
    bool cmp2(const cof x,const cof y){
    	return x.in<y.in;
    }
    queue<cof>q;
    int main(){
    	scanf("%d%d%d",&n,&m,&d);
    	for(int i(1);i<=n;i++){
    		scanf("%d",&a[i].time);
    		a[i].in=i;
    	}
    	sort(a+1,a+1+n,cmp1);
    	cnt++;
    	a[1].bl=cnt;
    	q.push(a[1]);
    	for(int i(2);i<=n;i++){
    		if(a[i].time>q.front().time+d){//可以继承 
    			a[i].bl=q.front().bl;
    			q.pop();
    			q.push(a[i]);
    		}
    		else{//新开一组 
    			cnt++;
    			a[i].bl=cnt;
    			q.push(a[i]);
    		}
    	}
    	sort(a+1,a+1+n,cmp2);
    	printf("%d
    ",cnt);
    	for(int i(1);i<=n;i++)printf("%d ",a[i].bl);
    	return 0;
    }
    
    
    
  • 相关阅读:
    C语言集锦(一) C代码生成图片:BMP、PNG和JPEG
    Win32 OpenGL标准例子
    Tcc学习笔记(一) 开篇
    C语言集锦(二) 图像显示 Windows和Linux
    矢量图和Word:EPS,PDF,EMF和SVG
    firefox浏览器无法显示bootstrap图标问题总结
    现代字体栈
    jquery 插件大全
    meta 详解,html5 meta 标签日常设置
    工厂方法模式Factory Method(Java实现)
  • 原文地址:https://www.cnblogs.com/soul-M/p/9660311.html
Copyright © 2020-2023  润新知