<Lanqiao Cup Software Competition>20 weeks of zero-based preparation--Lecture 2 of Week 8--Application of sorting

Students who have signed up for the Blue Bridge Cup Software Competition in April next year, if you are a freshman with zero foundation and are currently confused and don’t know what to do, you can take a look at this blog series:Collection of 20 weeks of preparation
For the complete schedule of 20 weeks, please click:20-week plan
Post 1 blog every week , 20 weeks in total (readers can choose "normal" and "fast forward" at their own pace ).
Focus on answering questions 3 times a week
, on Wednesday, Friday and Sunday evenings on the QQ group:

Insert image description here

Lecture 2 of Week 8:Application of sorting
  In algorithm competitions, you generally do not need to write these sorting algorithms yourself, but directly Use library functions, such as C++'s sort() function, Python's sort() and sorted() functions, and Java's sort() function.

1. C++ STL sort()

  has the following sorting function.
  sort (first, last, comp) Sorts the elements in the range [first, last). Note that the sorting range is [first, last), including first and excluding last. Comp is a comparison function, and sort() comes with 4 types of comp sorting: less, greater, less_equal, and greater_equal. By default, programs are sorted from small to large, and less can be omitted. You can also use a custom comparison function for sorting, see the examples in lines 3 and 4 below.

  stable_sort (first, last, comp) is similar to sort(), except that for elements with the same value in the [first, last) range, this function does not change their relative positions.
  ∼ partial_sort(first, middle, last, , comp) implements partial sorting by exchanging the storage locations of elements, and sorts the smallest (or largest) middle-first elements in the range [first, last) Move to the [first, middle) area and sort these elements in ascending (or descending) order.
  nth_element(first, nth, last, comp) When using the default ascending order, this function finds the kth smallest element e from a sequence (the sequence subscript starts from 0), and puts it e moves to the k-th position in the sequence. Moreover, after the entire sequence is processed by the nth_element() function, all elements before e are smaller than e, and all elements after e are larger than e.
  is_sorted (first, last, comp) Check whether the range [first, last) has been sorted. By default, it checks whether it is sorted in ascending order.
  The following is an example.

#include<bits/stdc++.h>
using namespace std;
bool my_less(int i, int j)     {
    
    return (i < j);}  //自定义小于
bool my_greater(int i, int j)  {
    
    return (i > j);}  //自定义大于

int main (){
    
    
    int a[]={
    
    1,3,2,2,6,8,5,4};
    sort(a+2,a+6);                        //对前4个排序,结果:1 3 2 2 6 8 5 4
    sort(a,a+8,less<int>());              //结果:1 2 2 3 4 5 6 8
    sort(a,a+8,my_less); 	              //自定义排序,结果:1 2 2 3 4 5 6 8
    sort(a,a+8,greater<int>());           //从大到小排序,结果:8 6 5 4 3 2 2 1
    sort(a,a+8,my_greater);               //结果:8 6 5 4 3 2 2 1
    stable_sort(a+3,a+8);                 //结果:8 6 5 1 2 2 3 4

    int b[]={
    
    3,7,2,5,6,8,5,4};
    partial_sort(b,b+3,b+8);              //结果:2 3 4 7 6 8 5 5
    partial_sort(b,b+3,b+8,greater<int>());   //结果:8 7 6 2 3 4 5 5
    if(is_sorted(b,b+3,greater<int>())) cout<<"is sorted"<<endl;  //输出:is sorted

    vector<int> c = {
    
    1,2,3,4,5,6,7,8};
    sort(c.begin(),c.end(),my_greater);      //结果:8 7 6 5 4 3 2 1

    string s="hello world";
    sort(s.begin(),s.end(),greater<char>());  
    cout<<s;                               //输出: wroolllhed    注意最后一个是空格
    return 0;
}

  Use the cmp() function and sort() to sort the structure, see the following example.
  C++'s sort() has two advantages: (1) it can be sorted on the original array without requiring new space; (2) it can be sorted on the local range of the array.

2. Python’s sort() and sorted()

  Python provides two sorting functions, sort() and sorted().
1. The difference between sort and sorted()
  sort() is a method applied to lists, while sorted can sort all iterable objects. . 
  A key difference is: sort sorts the original list, while sorted() produces a new list without changing the original list.
2. sorted()
  ˆ sorted(iterable, key=None, reverse=False)
  ˆ Parameter description: 3. Examples of sort() and sorted()   Return value: reordered list.   reverse: Sorting rule, reverse = True for descending order, reverse = False for ascending order (default).   key: The element used for comparison has only one parameter. The parameters of the specific function are taken from the iterable object, and an element in the iterable object is specified for sorting.
  iterable: iterable object.



a = [3,7,9,3,4,1,2]
a.sort()            #直接在a上升序排序,a改变了
print(a)            #[1, 2, 3, 3, 4, 7, 9]
b = sorted(a,reverse = True)
print(b)            #排序结果给b,输出:[9, 7, 4, 3, 3, 2, 1]
print(a)            #a不变,输出:[1, 2, 3, 3, 4, 7, 9]

a.sort(reverse = True)  #降序
print(a)            #输出:[9, 7, 4, 3, 3, 2, 1]

a = "abadae"
print(sorted(a))    #输出:['a', 'a', 'a', 'b', 'd', 'e']
#这样是错的:a.sort(),因为sort()应用在list上,a不是list

s1 = [('b', 'A', 15), ('c', 'B', 12), ('e', 'B', 10)]
s2 = sorted(s1, key=lambda s: s[2])                 # 按第3个排序,默认升序
print(s2)           #输出:[('e', 'B', 10), ('c', 'B', 12), ('b', 'A', 15)] 
s3 = sorted(s1, key=lambda s: s[2], reverse=True)   # 按第3个排序,降序
print(s3)           #输出:[('b', 'A', 15), ('c', 'B', 12), ('e', 'B', 10)]
 
s = "hello world"
s = ''.join(sorted(s, reverse=True))
#Python中字符串不可变,不能直接在原字符串上进行排序
#可以将字符串转换为列表进行排序,然后再转回字符串
print(s) #输出:wroolllhed     注意最后一个是空格

  Python's sort() cannot sort a part of the array, but can only sort the entire array; although sorted() can sort a part, it cannot sort the original array directly.

3. Java sort()

  There are Arrays.Sort() and Collections.sort().
  Arrays.sort() can sort arrays, strings, etc. Collections.sort() sorts the list collection, and the list can also contain numbers and strings. See the examples below for custom comparisons.
  Example:

import java.util.*;
public class Main {
    
    
    public static void main(String[] args) {
    
    
       int[] a = {
    
    8, 3, 6, 2, 3, 5, 9}; 
       Arrays.sort(a);                 //升序
       for (int num : a)   System.out.print(num+" ");  //输出: 2 3 3 5 6 8 9 
       System.out.println();
       
       Integer[] b = {
    
    2, 3, 4, 1, 0, 6, 5}; 
       Arrays.sort(b,Collections.reverseOrder());   //降序
       //不支持基本类型int,double,char,如果是int型需要改成Integer,float要改成Float
       for (int num : b)   System.out.print(num+" ");  //输出: 6 5 4 3 2 1 0      
       System.out.println();
       
       String s = "hello world";
       char[] chars = s.toCharArray();
       Arrays.sort(chars);
       s = new String(chars);   
       //Java中字符串是不可变的,因此不能直接在原字符串上进行排序。可以将字符串转换为字符数组进行排序,然后再将排序后的字符数组转换回字符串。
       System.out.println(s);     //输出: dehllloorw 
       
       ArrayList<Integer> list  = new ArrayList<>();
       list.add(36);
       list.add(52);
       list.add(15);
       Collections.sort(list);
       System.out.print(list);       //输出: [15, 36, 52]  
    }
}

4. Example questions

Example 1 Basic application of sorting

Oil pipeline problem
  given the y coordinates of n oil wells, sort them, y 0 ≤ y 1 ≤ . . . ≤ y n − 1 y_0≤y_1≤...≤y_{n-1} and0and1...andn1.
  Suppose the y coordinate of the main pipeline is m, then find ∣ y 0 − m ∣ + ∣ y 1 − m ∣ + . . . + ∣ y n − 1 − m ∣ |y_0-m|+|y_1-m|+...+|y_{n-1}-m| y0m+y1m+...+yn1The minimum of m.
  maffirmation y 0 y_0 and0小于 y n − 1 y_{n-1} andn1, the guess is the mean, or median. It is easy to prove that it is the median, for example, n=7, m is y 3 y_3 and3;n=8,m is y 3 y_3 and3or y 4 y_4 and4.
C++ 代码

#include<bits/stdc++.h>
using namespace std;
int y[10001];
int main(){
    
    
    int n; cin>>n;
    for (int i=0; i<n; i++)  {
    
    
        int x;
        cin>>x>>y[i];      //忽略x坐标
    }
    sort(y,y+n);           //对n个y值排序  
    int m = y[n/2];        //m是中位数
    int ans = 0;
    for (int i=0; i<n; i++)  ans += abs(m-y[i]);
    cout<<ans;
    return 0;
}

Java code

import java.util.*;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] y = new int[n];
        for (int i = 0; i < n; i++) {
    
    
            int x = sc.nextInt();
            y[i] = sc.nextInt();
        }
        Arrays.sort(y);
        int m = y[n/2];
        int ans = 0;
        for (int i = 0; i < n; i++)   ans += Math.abs(m - y[i]);
        System.out.println(ans);
    }
}

Python code

n = int(input())
y = []
for i in range(n):
    x, yi = map(int, input().split())
    y.append(yi)
y.sort()
m = y[n//2]
ans = 0
for i in range(n): ans += abs(m - y[i])
print(ans)

Example 2 Basic application of sorting

Sean's sorting

  Consider the simple and direct approach first. The question requires "A[i] > B[i] at all positions i". First sort A from small to large, and then enumerate the B array. For a certain B[i], if there is A[j]> ;B[i], then A[j]~A[n-1] are all legal. Find all such permutations, and that's the answer. But doing so is extremely computationally expensive.
  The question only requires A[i]>B[i], so the internal order of A[] and B[] has no impact on the answer. For position i, A[i] can be all elements in A[] that are greater than B[i]. Therefore, sorting A[] and B[] is convenient for calculation.
  First sort A[] and B[] from large to small, and then enumerate the B[] array. The steps are as follows:
  corresponding to B[0] The elements of A[] are all elements of A[] that are greater than B[0]. Let the range be A[i]~A[j].
  The element of A[] corresponding to B[1] includes two parts: the first part is A[i]~A[j], because B[1] ≤ B[0]; The second part is those elements of A[] after A[j] that are greater than B[1]. The first part can use the results of the previous step. In addition, because an A[] needs to be selected at the current position, the number that meets the conditions is reduced by one.
  Continue to enumerate the elements of other B[] until the end.
  Multiply the number of elements of A[] that meet the requirements each time to get the answer.
C++ code. Analyzing the computational complexity, sort() in lines 9 and 10 is O(nlogn), lines 12 and 13 combined is O(n2), and the total complexity is O(n2).

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,MOD=1e9+7;
int a[N],b[N];
int main() {
    
    
    long long n=0; cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++) cin>>b[i];
    sort(a,a+n,greater<int>());    //A数组从大到小排序
    sort(b,b+n,greater<int>());    //B数组从大到小排序
    long long cnt=0,ans=1;
    for(int i=0,j=0;i<n;i++) {
    
         //枚举每个B[i]
        while(j<n && a[j]>b[i])    //找所有大于b[i]的数
            cnt++,j++;
        ans *= cnt--;
        ans %= MOD;
    }
    cout<<ans<<endl;
}

Java code

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    
    
    static final int N = 100010;
    static final int MOD = 1000000007;
    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] a = new int[N];
        int[] b = new int[N];
        for (int i = 0; i < n; i++)     a[i] = scan.nextInt();
        for (int i = 0; i < n; i++)     b[i] = scan.nextInt();
        Arrays.sort(a, 0, n);                           //从小到大排序
        for (int i = 0; i < n/2; i++) 
{
    
    int tmp=a[i]; a[i]=a[n-1-i];a[n-1-i]=tmp;}   //从大到小
        Arrays.sort(b, 0, n);                           //从小到大排序
        for (int i = 0; i < n/2; i++) 
{
    
    int tmp=b[i]; b[i]=b[n-1-i];b[n-1-i]=tmp;}   //从大到小
        long cnt = 0, ans = 1;
        int j = 0;
        for (int i = 0; i < n; i++) {
    
    
            while (j < n && a[j] > b[i]) {
    
    
                cnt++;
                j++;            
            }
            ans *= cnt;
            cnt--;
            ans %= MOD;
        }
        System.out.println(ans);
    }
}

Python code

n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
a.sort(reverse=True)
b.sort(reverse=True)
cnt, ans = 0, 1
j = 0
for i in range(n):
    while j < n and a[j] > b[i]:
        cnt += 1
        j +=1
    ans *= cnt
    cnt -= 1
    ans %= int(1e9+7)
print(ans)

Example 3 Custom sorting comparison function

  Use this question to familiarize yourself with the custom comparison function in sort().
Digital sorting
C++ code. This question seems difficult to solve. In fact, it can be easily implemented by using the custom comparison function comp in sort (first, last, comp).

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[N], b[N];
int sum(int x){
    
                  //计算x的数位和
    int ans = 0;
    while(x)  ans += x % 10, x /= 10;
    return ans;
}
bool cmp(int x, int y){
    
         //自定义比较,数位和小的在前面
    if(b[x] == b[y])  return x < y;
    return b[x] < b[y];
}
int main(){
    
    
    int n, m;   cin >> n >> m;
    for(int i = 1; i <= n; i++) {
    
    
        a[i] = i;
        b[i] = sum(i);
    }
    sort(a + 1, a + 1 + n, cmp);
    cout<<a[m]<<endl;
    return 0;
}

java code. Notice how Arrays.sort() customizes the comparison.

import java.util.*; 
public class Main {
    
    
    public static int sum(int num) {
    
    
        int ans = 0;
        while(num>0) {
    
    
            ans+=num%10;
            num/=10;
        }
        return ans;
    }
    public static void main(String[] args) {
    
    
      Scanner scanner = new Scanner(System.in);
      int n = scanner.nextInt();
      int m = scanner.nextInt();
      int [][]a = new int[n][2];
      for (int i=0;i<n;i++){
    
    
          a[i][0] = sum(i+1);
          a[i][1] = i+1;
      } 
      Arrays.sort(a,(v1,v2)->{
    
    
          if (v1[0]!=v2[0])    return v1[0]-v2[0];          
          return v1[1]-v2[1];
      });
      System.out.println(a[m-1][1]);
    }
}

Python code. Use lambda to customize comparison.

def sum(x):    # 计算每一个数的数位和
    ans = 0
    while x:
        ans += x % 10
        x //= 10
    return ans
n=int(input())
m=int(input())
a=list(range(1,n+1))     #赋值a[0]~a[n],注意rang(1,n+1)最后一个是a[n]
a.sort(key=lambda i:sum(i))
print(a[m-1])

Example 4 Structure sorting

Queue to receive water
  Use this question to familiarize yourself with structure sorting
C++ code

#include<bits/stdc++.h>
using namespace std;
struct node{
    
     int t,id;};          //定义结构体a
struct node a[1010];              //定义结构体数组
bool cmp(node x,node y) {
    
     return x.t<y.t;}      //定义“小于”运算符
int main(){
    
    
    int n; cin>>n;
    for(int i=1; i<=n; i++){
    
    
        cin>>a[i].t;
        a[i].id=i;                 //序号存起来
    }
    sort(a+1,a+n+1,cmp);           //排序
    for(int i=1; i<=n; i++)        //输出
        cout<<a[i].id<<" ";
    cout<<endl;                    //换行
    double time=0;                 //总时间
    for(int j=n-1; j>=1; j--) {
    
        //等待人数,由n-1开始
        int i=n-j;                 //当前最少时间的人序号 + 要等待的人数=n
        time += a[i].t*j;          //累加
    }
    printf("%.2lf",time/n);        //算平均时间,保留两位小数
    return 0;
}

Java code

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        double time=0;
        node[] a=new node[n+10];
        for (int i = 1; i <=n ; i++) 
            a[i]=new node(i,sc.nextInt());
        Arrays.sort(a,1,n+1,(x,y)->(x.t-y.t));
        for (int i = 1; i <=n ; i++) 
            System.out.print(a[i].id+" ");
        for (int i = 1; i <=n; i++) 
            time+=a[i].t*(n-i);     
        System.out.println();
        System.out.printf("%.2f",time/n);
    }
}
class node{
    
    
    int id;
    int t;
    public node(int id, int t) {
    
    
        this.id = id;
        this.t = t;
    }
}

Python code

n = int(input())
t = list(map(int, input().split()))
a = [(id, e) for id, e in enumerate(t)]
a.sort(key=lambda x:x[1])
print(' '.join([str(i + 1) for i, e in a]))
time = [0] * n
tmp = 0
for i, (j, e) in enumerate(a):
    time[i] = tmp
    tmp += e
print('{:.2f}'.format(sum(time) / len(time)))

Example 5 Structure sorting

Divide the bananas
  This is a somewhat lengthy sorting question that requires multiple sorting: (1) Sort the bananas by quality; (2) Sort the monkeys by the assigned bananas; (3) The monkeys are sorted by number. It's better to use structure sorting.
C++ code

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int banana[N],part[N];   //香蕉、分成m份
struct Monkey{
    
    
    int w,id,y;    //猴子的重量、编号、吃到的香蕉
}mon[N];
bool com1(Monkey a, Monkey b){
    
     return a.w  > b.w;}  //比较重量
bool com2(Monkey a, Monkey b){
    
     return a.id < b.id;}  //比较编号
int main(){
    
    
    int n,m;   cin>>n>>m;
    for(int i=1;i<=n;i++) cin >> banana[i];
    sort(banana+1,banana+1+n);    //香蕉排序
    for(int i=1;i<=m;i++)    {
    
    
        cin >> mon[i].w;
        mon[i].id=i;
    }
    sort(mon+1,mon+1+m,com1);  //猴子按重量排序
    for(int i=1;i<=n;i++)
        part[i%m] += banana[n-i+1];   //把香蕉分成m份
    for(int i=1;i<=m;i++)
        mon[i].y = part[i%m];         //分给m个猴子
    sort(mon+1,mon+1+m,com2);      //按编号排序,也就是回到初始排序
    for(int i=1;i<=m;i++)
        cout<< mon[i].y <<" ";
    return 0;
}

Java code

import java.util.*;  
  
public class Main {
    
      
    static class Monkey {
    
      
        int w, id, y;   //猴子的重量、编号、吃到的香蕉  
        public Monkey(int w, int id, int y) {
    
      
            this.w = w;  
            this.id = id;  
            this.y = y;  
        }  
    }    
    public static void main(String[] args) {
    
      
        Scanner scanner = new Scanner(System.in);  
        int n = scanner.nextInt();  
        int m = scanner.nextInt();  
        ArrayList<Integer> banana = new ArrayList<>();  
        for (int i = 0; i < n; i++) banana.add(scanner.nextInt());          
        Collections.sort(banana);    
        ArrayList<Monkey> monkeys = new ArrayList<>();  
        for (int i = 0; i < m; i++) 
            monkeys.add(new Monkey(scanner.nextInt(), i + 1, 0));          
        Collections.sort(monkeys, (a, b) -> b.w - a.w);  //猴子按重量排序  
        int[] part = new int[m];  
        for (int i = 0; i < n; i++) 
            part[i % m] += banana.get(n - i - 1);  //把香蕉分成m份          
        for (int i = 0; i < m; i++) 
            monkeys.get(i).y = part[i % m];  //分给m个猴子          
        Collections.sort(monkeys, (a, b) -> a.id - b.id); //按编号排序,回到初始排序  
        for (int i = 0; i < m; i++) 
            System.out.print(monkeys.get(i).y + " ");  //输出每个猴子的香蕉数量          
    }  
}

Python code

n,m=map(int,input().split())
banana=list(map(int,input().split()))  #香蕉质量
banana.sort(reverse=True)              #香蕉排序
monkey=list(map(int,input().split()))  #猴子重量
id=[i for i in range(1,m+1)]           #猴子编号
part=[0 for i in range(1,m+1)]
weight=list(zip(id,monkey,part))
weight=map(list,weight)
weight=sorted(weight,key=lambda x:x[1],reverse=True) #猴子按重量排序
for i in range(len(banana)):    #把香蕉分成m份
    weight[i%m][2] += banana[i]
weight.sort()                      #猴子按编号排序
for i in range(len(monkey)):
    print(weight[i][2],end=' ')

5. Exercises

Statistics
Error tickets
Scholarships
Takeaway priority
Two-way sorting
What’s the lucky number
Insertion sorting
Ranking
Library management Member
Swiss Wheel
Sean's Monopoly

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/134768845