题解 P2652 【同花顺】

rui_er

2020-09-01 18:47:54

Solution

本题是一个有趣(?)的思维题,题意:要替换尽量少的牌,使得整套牌成为一个同花顺。 --- 思路:容易想到,我们保留现有的最长的一条同花顺,将剩余的牌替换掉即可。 具体做法: - 读入数据先按照花色、数字进行排序和去重。 - 枚举每一个点作为同花顺的右端点。 - 找到左侧可以连成同花顺的第一张牌,计算同花顺长度,更新最长的长度。 - 计算剩余的牌的数量,输出即可。 --- 代码: ```cpp //By: Luogu@rui_er(122461) #include <bits/stdc++.h> using namespace std; const int N = 1e5+5; int n, diff, ans; struct Node { int col, val; bool operator < (const Node &a) const { if(this->col != a.col) return this->col < a.col; return this->val < a.val; } bool operator == (const Node &a) const {return (this->col == a.col) && (this->val == a.val);} bool operator != (const Node &a) const {return !(*this == a);} Node() {} Node(int a, int b) : col(a), val(b) {} ~Node() {} }a[N], b[N]; int col[N], val[N]; void discretization() { sort(a+1, a+1+n); b[++diff] = a[1]; for(int i=2;i<=n;i++) { if(a[i] != a[i-1]) b[++diff] = a[i]; } for(int i=1;i<=diff;i++) { col[i] = b[i].col; val[i] = b[i].val; } } int main() { scanf("%d", &n); for(int i=1;i<=n;i++) scanf("%d%d", &a[i].col, &a[i].val); discretization(); for(int i=2;i<=diff;i++) { int uPos = lower_bound(val+(lower_bound(col+1, col+1+i, col[i])-col), val+i, val[i]-n+1) - val; ans = max(ans, i-uPos+1); } printf("%d\n", n-ans); return 0; } ```