• luoguP2652同花顺


    题目

    这道题,我们求最少更换多少张牌就能够满足同花顺

    然后我们反向思考一下:最少更换多少张 == 最多有多少张不用换

    然后我们考虑同花顺的定义:所谓同花顺,就是指一些扑克牌,它们花色相同,并且数字连续

    我们就会发现肯定是尽可能多的不动(而且最终构成的同花顺的起点或结尾可以是原有的扑克牌)

    所以我们就可以枚举每张牌作为构成的同花顺的末尾(先去重)

    (这里的去重指的是将花色相同,数字相同的扑克牌去掉)

    然后我们考虑一共有(n)张牌,然后花色为(a_{i}),数字为(b_{i})的牌作为当前枚举到的同花顺的末尾

    因为枚举到的最后一张扑克牌的数字为(b_{i}),花色为(a_{i}),所以以这张牌为结尾的同花顺的第一张牌一定是一张花色为(a_{i}),数字为(b_{i}-n+1)的扑克牌(最后得到的同花顺),因为我们要求最多有多少张不用更换,所以只需要考虑原扑克牌中(去重之后)有多少张扑克牌(设为(k))满足条件(a_{k} == a_{i})&&(a_{i}-n+1 leq a_{k} leq a_{i})

    上述情况总结为两点:

    • 与当前枚举的结尾花色不同的一定要更换
    • 与当前结尾如果花色相同,且数字 (>) (当前枚举到结尾的扑克牌的数字 - n),就不用更换

    我们先排序,使相同花色的在一起,并且满足相同花色的数字从小到大排列
    然后可以用(queue)维护,遇到新的不同的花色就清空队列,否则就删除队首不满足的,然后将当前这个枚举到的结尾插入队列,然后每次取个最大的(size),最后求得最大的不用更换的牌数(然后用总排数减去就是最终答案了)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5;
    int n, ans, cnt;
    struct node{
    	int x, y;
    }a[N], b[N]; 
    bool cmp(node op, node opp){
    	if(op.x == opp.x) return op.y < opp.y;
    	return op.x < opp.x;
    }
    queue<int> q;
    void cl(){
    	while(!q.empty()) q.pop();
    }
    int main(){
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i ++) scanf("%d %d", &a[i].x, &a[i].y);
    	sort(a + 1, a + n + 1, cmp);
    	for(int i = 1; i <= n; i ++){
    		if(a[i].x == a[i - 1].x && a[i].y == a[i - 1].y) continue;
    		b[++ cnt] = a[i];	//cout<<cnt<<"ssddd
    ";
    	}
    
    	for(int i = 1; i <= cnt; i ++){
    		if(b[i].x != b[i - 1].x) cl();
    	    while(q.size() && b[i].y - q.front() >= n) q.pop();
    		q.push(b[i].y);
    		ans = max(ans, (int)q.size()); 
    	}
    
    	ans = (n - ans);
    	printf("%d
    ", ans); 
    	fclose(stdin); fclose(stdout);
    	return 0;
    } 
    

    完美撒花✿✿ヽ(°▽°)ノ✿

  • 相关阅读:
    sed命令
    awk命令
    let命令
    首先看一下友晶DE-SOC开发板的user manual
    嵌入式FIFO核的调用
    嵌入式ROM核的调用
    用嵌入式块RAM IP核配置一个双口RAM
    如何利用Visio设计一个系统的结构图
    uart通讯协议
    按键消抖试验及一个数码管电子时钟的设计
  • 原文地址:https://www.cnblogs.com/wsdslll/p/13664734.html
Copyright © 2020-2023  润新知