首页 > 试题广场 >

编程题1

[编程题]编程题1
  • 热度指数:7425 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

P为给定的二维平面整数点集。定义 P 中某点x,如果x满足 P 中任意点都不在 x 的右上方区域内(横纵坐标都大于x),则称其为“最大的”。求出所有“最大的”点的集合。(所有点的横坐标和纵坐标都不重复, 坐标轴范围在[0, 1e9) 内)

如下图:实心点为满足条件的点的集合。请实现代码找到集合 P 中的所有 ”最大“ 点的集合并输出。




输入描述:
第一行输入点集的个数 N, 接下来 N 行,每行两个数字代表点的 X 轴和 Y 轴。
对于 50%的数据,  1 <= N <= 10000;
对于 100%的数据, 1 <= N <= 500000;


输出描述:
输出“最大的” 点集合, 按照 X 轴从小到大的方式输出,每行两个数字分别代表点的 X 轴和 Y轴。
示例1

输入

5
1 2
5 3
4 6
7 5
9 0

输出

4 6
7 5
9 0
通过80%超内存,求指教
nums = int(input())
points = []
results = []
for i in range(nums):
    points.append(list(map(int, input().split())))
points.sort(key=lambda x: x[0])
points.reverse()
results.append(points[0])
j = 0
for i in range(1, nums):
    if points[i][1] > results[j][1]:
        results.append(points[i])
        j += 1
results.sort()
for p in range(len(results)):
    print(results[p][0], results[p][1])
发表于 2020-06-23 21:33:59 回复(0)
对所有的坐标按 x 从大到小排序,如果 x 相等则按 y 从大到小排序。那么可以遍历所有坐标,只要当前点的 y 大于遍历过最大的 y ,那么这个点即是"最大的"

代码如下:
#include<bits/stdc++.h>
using namespace std;

const int maxn=5e5+5;

struct point
{
    int x;
    int y;
}p[maxn],ans[maxn];

bool cmpMaxtoMin(point a,point b)
{
    if(a.x==b.x)
        return a.y>b.y;
    return a.x>b.x;
}

bool cmpMintoMax(point a,point b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&p[i].x,&p[i].y);
        
    sort(p+1,p+1+n,cmpMaxtoMin);
    
    int len=0,max_y=-1;
    for(int i=1;i<=n;++i)
        if(p[i].y>max_y)
            ans[len++]=p[i],max_y=p[i].y;
    
    sort(ans,ans+len,cmpMintoMax);
    for(int i=0;i<len;++i)
        printf("%d %d\n",ans[i].x,ans[i].y);
    return 0;
}

编辑于 2019-04-27 10:12:26 回复(0)
cnt =int(input())
every =[]
result =[]
for i in range(cnt):
    num =[int(x) for x in input().split()]
    every.append(num)
every.sort(key=lambda t:t[0])
maxY =-1
for i in reversed(range(len(every))):
    if every[i][1] > maxY:
        result.append(every[i])
        maxY =every[i][1]
for i in reversed(range(len(result))):
    print(result[i][0], result[i][1])
算法和热评第一的大佬一样的……70% 超时或者80%超内存交替出现……有没有大佬救救我
编辑于 2019-04-25 16:18:40 回复(0)
N=eval(input())
xy=[]  for i in range(N):
    x,y=map(int,input().split())    xy.append((x,y))
g=[x for x in xy]   for i in range(len(xy)):
    a,b=xy[i]  for j in range(len(xy)):  if xy[j][0] > a and xy[j][1]>b:
            g.remove((a,b)) break b=sorted(g,key=lambda k: k[1],reverse=True)  for i in range(len(b)):  print(b[i][0],b[i][1])
这个网站上的有问题,亲自实践无论是他给出的5个坐标,还是10个坐标,我写的程序都没有错误,但是他却提示结果判断错误

发表于 2018-12-19 22:21:26 回复(0)
#include<iostream>
#include<algorithm>
using namespace std;

struct point{
    int x, y;
};

bool cmp(point a, point b)
{
    return a.x>b.x;
}
int main()
{
    int N;
    cin>>N;
    point p[N];
    int x,y;
    for(int i=0; i<N; ++i)
    {
        scanf("%d%d", &x, &y);
        p[i].x = x;
        p[i].y = y;
    }
    sort(p, p+N, cmp);
    int len = 1;
    int curY = p[0].y;
    for(int i=1; i<N; ++i)
    {
        if(p[i].y>curY)
        {
            curY = p[i].y;
            p[len].x = p[i].x;
            p[len].y = p[i].y;
            ++len;
        }
    }
    for(int i=len-1; i>=0; --i)
        printf("%d %d\n", p[i].x, p[i].y);
    return 0;
}

使用cin cout时间运行通不过

发表于 2018-06-19 11:18:19 回复(0)
AC80%,这题用python总超内存啊😭
n = int(input())
points = []
for _ in range(n):
    points.append(list(map(int, input().split())))
points.sort(key=lambda x: x[0])
# 计算从i~n-1的数据点中纵坐标最大的值
maxY = [0]*n
maxY[n - 1] = points[n - 1][1]
for i in range(n - 2, -1, -1):
    maxY[i] = max(points[i][1], maxY[i + 1])
# 求最大点
for i in range(n - 1):
    if points[i][1] > maxY[i + 1]:
        print(str(points[i][0]) + " " + str(points[i][1]))
# 横坐标最大的点一定是“最大的”点
print(str(points[n - 1][0]) + " " + str(points[n - 1][1]))


发表于 2020-12-09 16:57:23 回复(0)
只需对所有点的x坐标进行降序的排序,则第一个点一定是最大点,后面的点要想成为最大点,只需其y值大于前面的最大的y值即可。这样找到的点是根据x从大到小排列的,输出只需倒序输出就行。
代码如下:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct Point {
    int x;
    int y;
};
Point p[500002];
bool cmp(const Point &a, const Point &b) {
    return a.x > b.x;
}
int main() {
    int N, x, y;
    while(scanf("%d", &N) != EOF) {
        for (int i = 0; i < N; i++) {
            scanf("%d%d", &x, &y);
            p[i].x = x;
            p[i].y = y;
        }
        sort(p, p + N, cmp);
        int maxy = 0;
        int len = 0;
        for (int i = 0; i < N; i++) {
            if (i == 0) {
                maxy = p[i].y;
                len += 1;
            }
            else if(p[i].y > maxy) {
                p[len].x = p[i].x;
                p[len].y = p[i].y;
                maxy = p[i].y;
                len += 1;
            }
        }
        for (int i = len - 1; i >= 0; i--) {
             printf("%d %d\n", p[i].x, p[i].y);
        }
    }
    return 0;
}
</pre>
编辑于 2017-12-27 21:07:20 回复(2)

70%超时。。求大佬们提意见~~啥意见都行

import java.util.*; 
public class Main { 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in); int num = Integer.valueOf(scanner.nextLine());
        Point[] points = new Point[num];
        List maxPoints = new ArrayList();
        String[] line; for (int i = 0; i < num; i++) {
            line = scanner.nextLine().trim().split(" ");
            points[i] = new Point(Integer.valueOf(line[0]), Integer.valueOf(line[1]));
        }
        Arrays.sort(points);
        maxPoints.add(points[num - 1]); 
        int maxY = points[num - 1].y; for (int i = num - 2; i >= 0; i--) { if (points[i].y >= maxY) {
                maxPoints.add(points[i]);
                maxY = points[i].y;
            }
        }
        Collections.reverse(maxPoints);
        maxPoints.forEach(System.out::println);
    } 
    static class Point implements Comparator<Point> { 
        int x; 
        int y; 
        public Point(int x, int y) { 
            this.x = x; this.y = y;
        } 
        [@Override](/profile/992988)  
        public int compareTo(Point o) { 
            return Integer.compare(this.x, o.x);
        } 
        [@Override](/profile/992988)  
        public String toString() { 
            return x + " " + y;
        }
    }
}

编辑于 2018-04-03 17:51:02 回复(6)
if __name__ == "__main__":
    n = int(input())
    a = []
    for _ in range(n):
        a.append(list(map(int,input().split())))
    a.sort(key=lambda x: x[0])

    j = len(a) - 2
    tmpy = a[-1][1]

    for i in range(len(a) - 1, -1, -1):
        if tmpy < a[i][1]:
            tmpy = a[i][1]
            a[j] = a[i]
            j -= 1
    for k in range(j + 1, len(a)):
        print(a[k][0], a[k][1])
        
通过80%,在原来的数组里修改,想不通为啥还是爆内存,怀疑这个python有问题,欢迎大佬指正
编辑于 2019-08-13 20:50:18 回复(2)

分析:

  • 1.对 X进行排序
  • 2.按照 X从大到小遍历所有的点, 判断当前的 Y是否大于最大 Y, 如果大于, 则是最大点, 保存到数组中.
  • 3.最后倒序输出数组

不能完全 AC的原因:
尽量使用 scanf/printf函数, 效率要比 cin/cout高

#include 
using namespace std;
#define nullptr NULL

struct Point {
    int x;
    int y;
};

// 比较器, 按 X降序 
bool cmp(const Point a, const Point b) {
    return a.x > b.x;
}

int main()
{
    int n;
    cin >> n;
    Point point[n];
    int x, y;
    for(int i = 0; i < n; i++) {
      scanf("%d%d", &x, &y);
      point[i].x = x;
      point[i].y = y;
    }
    //排序
    sort(point, point + n, cmp);
     // 找出最大点 
    int len = 1;
    int curY = point[0].y;
    for(int i = 1; i < n; i++) {
        if(point[i].y > curY) {        // 这里取不取等都可以 AC 
            curY = point[i].y;
            point[len].x = point[i].x;
            point[len].y = point[i].y;
            len++;
        }
    }
    for(int i = len - 1; i >= 0; i--) {
         printf("%d %d\n", point[i].x, point[i].y);
    }
    return 0;
}
编辑于 2018-03-24 11:14:34 回复(0)
只需对所有点的x坐标进行降序的排序,则第一个点一定是最大点,后面的点要想成为最大点,只需其 y 值大于前面的最大的 y 值即可。这样找到的点是根据x从大到小排列的,输出只需倒序输出就行。
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为80.00%
请指教,qq3382885270
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] keyArr = new int[N];
        HashMap<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < N; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            keyArr[i] = x;
            hashMap.put(x, y);
        }
        Arrays.sort(keyArr);
        ArrayList<Integer> ans = new ArrayList<>();
        //key等价于x,value等价于y
        int maxKey = keyArr[N - 1];  //将x排好序后,那么x最大的一定是“最大点”(记作A)
        int maxValue = hashMap.get(maxKey);
        ans.add(maxKey);
        for (int i = N - 2; i >= 0; i--) { //从倒数第二个开始,如果他想成为“最大点”,则现在存在的“最大点”A不能在它的右上方,那么他只需要y比“最大点”A大
            int key = keyArr[i];
            int value = hashMap.get(key);
            if (value > maxValue) {
                ans.add(keyArr[i]);
                maxValue = value;
            }
        }
        for (int i = ans.size() - 1; i >= 0; i--) {
            int key = ans.get(i);
            System.out.println(key + " " + hashMap.get(key));
        }
        sc.close();
    }
}


编辑于 2020-08-15 19:40:26 回复(0)
python AC 50% 超时了,感觉这道题python没办法不超时。。sort自己写可能会好点,但是python那么多好用的包和函数不就是拿来用的么QAQ,不想改了,50就50,不捞我就独自美丽
n = int(input())
listx=[]
listy=[]
for i in range(n):
    x,y=list(map(int, input().split(" ")))
    listx.append(x)
    listy.append(y)
Z = zip(listx,listy)
Z = sorted(Z)
newx,newy=zip(*Z)
newx=list(newx)
newy=list(newy)
for i in range(n):
    if newy[i]== max(newy[i:]):
        print(newx[i],newy[i])

发表于 2020-05-10 15:47:08 回复(0)
N=int(input())
loc=[]

for i in range(N):
    a=[int(i) for i in input().split()]
    loc.append(a)
loc.sort(key=lambda t:(t[0],t[1]))
printout=[loc[-1]]
i=0
while (N>i):
    if printout[-1][1]<loc[N-2-i][1]:
        printout.append(loc[N-2-i])
    i+=1
printout.sort()
for i in printout:
    print(i[0],i[1])

发表于 2018-09-02 14:42:04 回复(3)
内存超限:您的程序使用了超过限制的内存
case通过率为80.00%
N= int(input())
l_p = []
for i in range(N):
    l_p.append( list(map(int, input().split(' '))) )
l_p.sort(key = lambda x : x[0], reverse=True)
res = []
y_max = l_p[0][1]
for item in l_p :
    if item[1] >= y_max : 
        y_max = item[1]
        res.append(item)
#res.sort()
for i in range(len(res)) :
    print(res[len(res)-1-i][0], res[len(res)-1-i][1])
发表于 2020-11-22 19:15:50 回复(0)
不用遍历全部元素!
for(逐个加入新点){
只需要找到横坐标比新输入点大的第一个点,设xk
    若新点<yk,那么不用加入新点,直接返回这次循环。
    否则这个点从该点开始逐步向左边遍历,如果遇到的点在新点的下方,说明这个点应该删除,直到遇到第一个纵坐标大于该新点的点(因为前面的点纵坐标比现在遇到的还要大)
}

我觉得我的思路没有问题,但是只ac了7道,希望各位大佬能指正一下

#include<bits/stdc++.h>
using namespace std;

void searchForward(map<int,int> &points,map<int,int>::iterator &ub,int x, int y,vector<int> &remove,bool &insert){
    map<int,int>::iterator it=ub;
    for(;it!=points.begin();it--){
        if(x<it->first){
            if(y<=it->second){
                insert=false;
                break;
            }
        }else{//replace here
            if(it->second<=y){
                remove.emplace_back(it->first);
            }else{
                break;
            }

        }
        
    }
    if(x<it->first){
        if(y<=it->second){
            insert=false;
            return;
        }
    }else{//replace here
        if(it->second<=y){
            remove.emplace_back(it->first);
        }else{
            return;
        }

    }
}

void update(map<int,int> &points,int x, int y){
    vector<int> remove;
    bool insert=true;

    map<int,int>::iterator ub=points.upper_bound(x);
    if(ub==points.end()){//x is the last
        if(y>=ub->second){
            searchForward(points,ub,x,y,remove,insert);
        }else{
            points[x]=y;
            return;
        }
    }else{
        if(ub==points.begin()){//x is the first one
            if(y<=ub->second){return;}//do not insert x
            else{//directly insert x and skip other check
                points[x]=y;
                return;
            }
        }else{
            searchForward(points,ub,x,y,remove,insert);
        }
    }
    if(insert){
        points[x]=y;
    }
    for(vector<int>::iterator it=remove.begin();it!=remove.end();it++){
        points.erase(*it);
    }

}
int main(){
    int n,x,y;
    map<int,int> points;
    cin>>n;
    scanf("%d %d",&x,&y);
    points[x]=y;
    for(int i=0;i<n-1;i++){

        scanf("%d %d",&x,&y);
        update(points,x,y);
    }
    for(map<int,int>::iterator it=points.begin();it!=points.end();it++){
        printf("%d %d\n",it->first,it->second);
    }
    return 0;
}


发表于 2022-10-28 21:52:14 回复(0)
有没有大佬帮忙看一眼呢,写了半天好不容易想明白,但是超时了
n = int(input())
points = []
for i in range(n):
    x, y = map(int, input().strip().split(' '))
    points.append((x,y))
    
points.sort(key=lambda a:-a[1])
x_axis = -1
for x, y in points:
    if x > x_axis:
        print(x, y)
        x_axis = x

发表于 2022-09-11 18:26:06 回复(0)
内存不足
N=int(input())
i=0
X=[]
Y=[]
while i<N:
    a,b=input().split(" ")
    X.append(int(a))
    Y.append(int(b))
    i=i+1
datas=zip(X,Y)
datass1=sorted(datas,key=lambda x:x[0])
datass2=zip(*datass1)
X,Y = [list(x) for x in datass2]
for i in range(0,N-1):
    if Y[i]==max(Y[i:N]):
        print(X[i],Y[i],end='\n')
        i=i+1
    else:
        i=i+1   
print(X[N-1],Y[N-1])

编辑于 2022-09-04 17:09:01 回复(0)
N = int(input())
xy = []
for i in range(N):
    x_y = input()
    x_y_list = x_y.split(' ')
    xy.append([int(x_y_list[0]), int(x_y_list[1])])
sort_x = sorted(xy,key=lambda x:x[0],reverse=True)
y_max = sort_x[0][1]
p_max_lst = []
p_max_lst.append(sort_x[0])
for i in range(1,len(xy)):
    if sort_x[i][1]>y_max:
        p_max_lst.append(sort_x[i])
        y_max = sort_x[i][1]
for k,v in p_max_lst:
    print(k,v)

发表于 2022-08-04 16:18:55 回复(0)
java版本,用的堆排序,一开始输入用的scanner输出用println,通过70%,改完输入和输出后全部通过。输入的写法参考 Faster Input for Java (ku.ac.th)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        int num=Reader.nextInt();
        PriorityQueue<int[]> points=new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o2[1]-o1[1];
            }
        });
        for (int i = 0; i < num; i++) {
            int x=Reader.nextInt();
            int y=Reader.nextInt();
            points.offer(new int[]{x,y});
        }
        int[] p= points.poll();
        int x=p[0];
        int y=p[1];
        PrintWriter out=new PrintWriter(System.out);
        out.println(x+" "+y);
        while (!points.isEmpty()){
            p= points.poll();
            if (p[0]>x){
                x=p[0];
                out.println(p[0]+" "+p[1]);
            }
        }
        out.flush();
    }
    static class Reader {
        static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        static StringTokenizer tokenizer = new StringTokenizer("");
        static String next() throws IOException {
            while (!tokenizer.hasMoreTokens()){
                tokenizer=new StringTokenizer(reader.readLine());
            }
            return tokenizer.nextToken();
        }
        static int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
    }
}


发表于 2022-07-17 00:47:43 回复(1)
求指导~ 给的测试过了,但是最后的没有通过
思路:全部输入数据,对于第一个(x,y),找横坐标x之后l2[1]大于y的数,如果能找得到那么他就不是最大值,l3设F,否则即为最大值
代码:
a =int(input())
l1 =[] # 记录原始  5 3
l2 =[] # 记录分割 ['5','3']
l3 =[] #    T/F判断
# 初始化
fori inrange(a):
    l1.append(input())
    l2.append(l1[i].split(' '))
    l3.append(True)
查找最大值
fori in range(a):
    forj inl2[i+1:]:
        ifint(j[1])>=int(l2[i][1]):
            l3[i]=False
            break
# 根据T 输出最大值
fori inrange(a): 
    ifl3[i]:
        print(l1[i])

发表于 2022-04-30 20:20:02 回复(0)