列表

详情


NC21434. 肥宅の正经算法

描述

西体现在有 n 个肥宅笔直躺在地上,每个肥宅一端在坐标  a ,另一端在坐标 b (一维坐标) ,可以视为一条线段,任意两个肥宅之间是平行的,因此他们可以视为数轴上的线段。
现在要选出其中 k 个肥宅,使得这 k 个肥宅所在的坐标区域两两不重合,请问 k 最大能取多少?
重合是指线段之间相交长度大于0,首尾相接不视为重合。

输入描述

第一行为一个正整数 n 表示有 n 个肥宅;

在接下来的 n 行中,每行有两个数字,ai,bi表示第 i 个肥宅表示的线段端点。

输出描述

输出一行一个整数表示 k 能选取的最大值。

示例1

输入:

3
0 2
2 4 
1 3

输出:

2

说明:

样例中最多选取两个肥宅能满足互相不重合的要求,即选取第一个和第二个肥宅

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 702ms, 内存消耗: 19488K, 提交时间: 2023-03-27 09:41:30

#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>

using namespace std;

#define out(x) cout << #x << '=' << x << endl
#define out2(x, y) cout << #x << '=' << x << ',' << #y << '=' << y << endl 
#define no cout << "No" << endl; return
#define yes cout << "Yes" << endl; return
#define outvec(a) for (auto &v : a) { cout << v << ' '; } cout << endl
#define lowbit(x) (x & -x)
#define gcd __gcd 
#define inf 0x3f3f3f3f3f3f3f3fLL
#define infi 0x3f3f3f3f

using ll = long long;
using pii = pair<int, int>;

 

void solve() {
	int n;
    cin >> n ;
    vector<pii> v(n + 1);
    vector<int> p;
    for (int i = 1; i <= n; i++) {
        cin >> v[i].first >> v[i].second;
        p.push_back(v[i].first);
        p.push_back(v[i].second);
    }
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    vector<int> dp(p.size());
    sort(v.begin(), v.end(), [&](pii a, pii b) -> int {
        return a.second < b.second;
    });
    int j = 1;
    auto index = [&](int x) -> int {
        return lower_bound(p.begin(), p.end(), x) - p.begin();
    };
    for (int i = 0; i < p.size(); i++) {
        if (i) dp[i] = dp[i - 1];
        while (j <= n && index(v[j].second) == i) {
            dp[i] = max(dp[i], dp[index(v[j].first)] + 1);
            j++;
        }
    }
    cout << dp[p.size() - 1] << endl;
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t = 1;
	//cin >> t;
    
    while (t--) {
    	solve();
	}
}

Java 解法, 执行用时: 3769ms, 内存消耗: 59004K, 提交时间: 2023-05-23 17:20:31

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n = sc.nextInt();
        int[][] vec = new int[n][2];
        for (int i = 0; i < n; i++) {
            vec[i][0] = sc.nextInt();
            vec[i][1] = sc.nextInt();
        }
        Arrays.sort(vec,(a,b)->a[1]-b[1]);
        int res = 1,end = vec[0][1];
        for (int i = 1; i < n; i++) {
            if(vec[i][0]>=end){
                res++;
                end = vec[i][1];
            }
        }
        System.out.println(res);
    }
}

C++14(g++5.4) 解法, 执行用时: 1028ms, 内存消耗: 8184K, 提交时间: 2020-01-22 23:38:04

#include<bits/stdc++.h>
using namespace std;
pair<int,int>a[1000005];
int main(){
	int i,j,m,n,k=0,result=1;
	cin>>n;
	for(i=0;i<n;i++)
		cin>>a[i].second>>a[i].first;
	sort(a,a+n);	
	for(i=0;i<n;i++)
		if(a[i].second>=a[k].first){
		k=i;
		result++;
		}
	cout<<result;	
	return 0;
}
 

C++11(clang++ 3.9) 解法, 执行用时: 853ms, 内存消耗: 8296K, 提交时间: 2020-03-13 11:16:29

#include<bits/stdc++.h>
using namespace std;
pair<int,int>a[1000005];
int main()
{
	int i,j,m,n,k=0,result=1;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i].second>>a[i].first;
	sort(a,a+n);
	for(i=0;i<n;i++)
	if(a[i].second>=a[k].first)
	{
		k=i;
		result++;
	}
	cout<<result;
	return 0;
}

上一题