zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
    
  • 相关阅读:
    git常用命令
    git误删文件找回方法/git版本回退方法
    如何解决inline和linline-block在浏览器中的间距问题
    windows系统如何添加ssh key到github
    如何使用git命令添加文件和提交文件
    sublime text常用快捷键
    sublime text3好用的插件
    Atom编辑器的插件
    使用SharedPreference保存用户数据的步骤
    解析xml文件步骤 -- pullparser
  • 原文地址:https://www.cnblogs.com/soul-M/p/9660311.html
Copyright © 2011-2022 走看看