1 条题解

  • 0
    @ 2025-7-6 19:35:50

    题目中给定的为等腰直角三角形。

    考虑对于坐标轴上的等腰直角三角形,只给定了顶点坐标,我们该如何判断两个等腰直角三角形为包含关系?

    其实很简单,只要判断等腰直角三角形的左下角端点右下角端点所构成的区间是否为包含关系即可。

    则问题我们就转换为,给定 nn 个区间,问有多少个区间与其他区间均不被其他区间中任意一个区间所包含。

    O(n2)O(n^2)

    直接枚举任意 22 个点对,然后验证是否是被包含关系即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5 + 10;
    int n;
    
    struct node {
        int x, y;
    } a[N];
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
    
        cin >> n;
        for (int i = 1; i <= n; i++) {
            int x, y;
            cin >> x >> y;
            a[i].x = x - y;
            a[i].y = x + y;
        }
    
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            bool contained = false;
            for (int j = 1; j <= n; j++) {
                if (i == j) continue;
                // 如果 a[i] 被 a[j] 包含
                if (a[j].x <= a[i].x && a[i].y <= a[j].y) {
                    contained = true;
                    break;
                }
            }
            if (!contained) ans++;
        }
    
        cout << ans << '\n';
    }
    
    

    O(nlogn)O(n\log n)

    对每个区间进行排序,以左端点为第一关键字进行升序排序,右端点为第二关键字进行降序排序。

    维护一个区间 [l,r][l,r],该区间为当前的最大区间。

    如果当前区间超出当前区间范围,则更新区间,否则记录答案。

    注意去重。

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> PII;
    const int N=1e5+10;
    int n;
    struct node{
    	int x;
    	int y;
    } a[N];
    bool cmp(const node a,const node b){
    	if(a.x!=b.x) return a.x<b.x;
    	return a.y>b.y;
    }
    int main(){
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		int x,y;
    		cin>>x>>y;
    		a[i].x=x-y;
    		a[i].y=x+y;
    	}
    	sort(a+1,a+n+1,cmp);
    	int l=-1,r=-1;
    	int ans=0;
    	for(int i=1;i<=n;i++){
    		int x=a[i].x,y=a[i].y;
    		if(l==-1 && r==-1){
    			l=x;
    			r=y;
    			if((x == a[i-1].x && y == a[i-1].y)||(x == a[i+1].x && y== a[i+1].y)){
    				continue;
    			}	
    			ans++;
    		}
    		
    		if(x>=l && y<= r) continue;
    		l=x,r=y;
    		if((x == a[i-1].x && y == a[i-1].y)||(x == a[i+1].x && y== a[i+1].y)){
    			continue;
    		}	
    		ans++;
    	}
    	cout<<ans;
    }
    
    • 1

    信息

    ID
    171
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    86
    已通过
    9
    上传者