第4章 排序

A1012

#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>

using namespace std;

unordered_map<string, vector<int>> grades;
vector<int> q[4];  // A: q[0], C: q[1], M: q[2], E: q[3]   q就是一个 vector数组

int get_rank(vector<int> a, int x)       // get_rank(q[i], grades[id][i]);
{
    int l = 0, r = a.size() - 1;

    while (l < r)             //通过 2分 查找法,找到 排名
    {
        int mid = l + r + 1 >> 1;            //>>表示是 除以2
        if (a[mid] <= x) l = mid;
        else r = mid - 1;
    }

    return a.size() - l;
}

int main()
{
    int n, m;
    cin >> n >> m;

    for (int i = 0; i < n; i ++ )
    {
        string id;

        int t[4] = {0};     //这一步不可少后年要累加          //这个t 存放的 就是 ACME的成绩
        cin >> id;
        for (int j = 1; j < 4; j ++ )
        {
            cin >> t[j];
            t[0] += t[j];
        }
        t[0] = round(t[0] / 3);

        for (int j = 0; j < 4; j ++ )
        {
            q[j].push_back(t[j]);
            grades[id].push_back(t[j]);
        }
    }

    for (int i = 0; i < 4; i ++ ) sort(q[i].begin(), q[i].end());        //按照 成绩 升序 排列

    char names[] = "ACME";
    while (m -- )
    {
        string id;
        cin >> id;
        if (grades.count(id) == 0) puts("N/A");
        else
        {
            int res = n + 1;         //找到 当前的 最小 排名
            char c;

            for (int i = 0; i < 4; i ++ )
            {
                int rank = get_rank(q[i], grades[id][i]);     //q[i]就是 要把 查询的 数组 给过去,grades[id][i]就是要 查找的 值

                if (rank < res)    //更新 最小 排名
                {
                    res = rank;
                    c = names[i];
                }
            }

            cout << res << ' ' << c << endl;
        }
    }

    return 0;
}

A1022


#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>         //stringstream的用法

using namespace std;

struct Book
{
    string id, name, author;
    set<string> keywords;           //set结构
    string publisher, year;
};

int main()
{
    int n, m;
    cin >> n;        //输入n个书

    vector<Book> books;         //设置一个结构 vector
    
    while (n -- ) 
    {
        string id, name, author;
        cin >> id;
        getchar();            //读入getline之前,需要getchar一个 空格
        getline(cin, name), getline(cin, author);
        
        //读入这个关键字一串,不知道有多少个,
        string line;                //读入关键字
        getline(cin, line);         //读入一串 关键字
        
          //使用stringstream函数可以帮助我们提取需要的字符
        //stringstream ssin(line)将line初始化为一个字符流为ssin
        stringstream ssin(line);           
        
        string keyword;          //一个是string类型的 变量,一个是string类型的 set
        set<string> keywords;
        
        //将字符流中的信息读入keyword中
        while (ssin >> keyword) keywords.insert(keyword);     
            
        string publisher, year;
        getline(cin, publisher);
        cin >> year;
        books.push_back({id, name, author, keywords, publisher, year});
    }

    cin >> m;           //输入m个询问
    getchar();          //读入一个空格,因为下面要用getline
    string line;
    
    while (m -- )
    {
        getline(cin, line);             //读入一个字符串并输出
        cout << line << endl; 
        
        string info = line.substr(3);       //前3位是一个数字,冒号,空格
        char t = line[0];
        
        vector<string> res;
        
        if (t == '1')            //表示书名
        {
            for (auto& book : books)
                if (book.name == info)
                    res.push_back(book.id);
        }
        else if (t == '2')          //表示作者的名字
        {
            for (auto& book : books)          
                if (book.author == info)
                    res.push_back(book.id);
        }
        else if (t == '3')          //关键字
        {
            for (auto& book : books)
                if (book.keywords.count(info))
                    res.push_back(book.id);
        }
        else if (t == '4')          //出版商的名字
        {
            for (auto& book : books)
                if (book.publisher == info)
                    res.push_back(book.id);
        }
        else                                    //年份
        {
            for (auto& book : books)
                if (book.year == info)
                    res.push_back(book.id);
        }

        if (res.empty()) puts("Not Found");
        else
        {
            sort(res.begin(), res.end()); 
            for (auto id : res) cout << id << endl;
        }
    }

    return 0;
}

A1025

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 110;

struct Student
{
    string id;
    int grade;
    int location_number, local_rank, final_rank;

    bool operator< (const Student& t) const                         //重载函数
    {
        if (grade != t.grade) return grade > t.grade;       
        return id < t.id;
    }
};

vector<Student> grades[N];    
vector<Student> all;        //总的 结构 vector

int main()
{
    int n;
    cin >> n;               //输入n个值
    
    for (int i = 1; i <= n; i ++ )                //i值 从1开始,一直到n
    {
        int k;
        cin >> k;
        for (int j = 0; j < k; j ++ )
        {
            string id;
            int grade;
            cin >> id >> grade;
            grades[i].push_back({id, grade, i});
        }

        auto& g = grades[i];
        sort(g.begin(), g.end());
        
        for (int i = 0; i < g.size(); i ++ )
        {
            if (!i || g[i].grade != g[i - 1].grade)
                g[i].local_rank = i + 1;
            else
                g[i].local_rank = g[i - 1].local_rank;
            all.push_back(g[i]);
        }
    }

    sort(all.begin(), all.end());
    for (int i = 0; i < all.size(); i ++ )
        if (!i || all[i].grade != all[i - 1].grade)
            all[i].final_rank = i + 1;
        else
            all[i].final_rank = all[i - 1].final_rank;

    cout << all.size() << endl;
    for (auto& s : all)
        cout << s.id << ' ' << s.final_rank << ' ' << s.location_number << ' ' << s.local_rank << endl;

    return 0;
}


A1028


/*
    c为1,按照id的升序
    c为2,按照名字的升序
    c为3,按照成绩的升序

    如果有相同的名字和成绩,按照id的升序

*/

#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=100010;

int n;

struct node
{
    string id;
    string name;
    int grade;
}Node[maxn];

bool cmp1(node a,node b)
{
    if(a.id!=b.id)
        return a.id<b.id;
}

bool cmp2(node a,node b)
{
    if(a.name!=b.name)
        return a.name<b.name;
    else
        return a.id<b.id;
}

bool cmp3(node a,node b)
{
    if(a.grade!=b.grade)
        return a.grade<b.grade;
    else
        return a.id<b.id;
}

int main()
{
    int T;
    scanf("%d %d", &n, &T);   //将cin改为scanf 就不会超时
    for(int i=0; i<n; i++)
    {
        char name[10],id[10];      //注意这个输入
        int grade;
        scanf("%s %s %d",id,name,&grade);      //注意id和name前面没有&,grade前面有&
        Node[i]={id,name,grade};
    }


    if(T==1)
        sort(Node,Node+n,cmp1);
    else if(T==2)
        sort(Node,Node+n,cmp2);
    else if(T==3)
        sort(Node,Node+n,cmp3);

    for(int i=0; i<n; i++)
        cout << Node[i].id << " " << Node[i].name << " " << Node[i].grade << endl;

    return 0;

}

A1039


#include<iostream>
#include<unordered_map>
#include<set>
#include<cstring>
#include<vector>
using namespace std;

const int maxn=41000;

unordered_map<string,set<int>> g;

vector<string> name;

int n,k;

int main()
{
    scanf("%d %d",&n,&k);
    for(int T=1; T<=k; T++)
    {
        int course,num;
        scanf("%d %d",&course,&num);
        for(int j=0; j<num; j++)
        {
            char name[6];
            scanf("%s",name);
            g[name].insert(course);
        }
    }

    for(int i=0; i<n; i++)
    {
        char temp[6];
        scanf("%s",temp);
        name.push_back(temp);
    }

    for(int i=0; i<n; i++)
    {
        cout << name[i] << " " << g[name[i]].size();
        for(auto kk=g[name[i]].begin(); kk!=g[name[i]].end(); kk++)
            cout << " " << *kk;
        cout << endl;
    }

    return 0;
}

A1052


#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn=100010;

int n;

struct node
{
    string address;
    int key;
    string next;

    bool operator <(const node &t) const
    {
            return key<t.key;
    }

};

char head[6];

unordered_map<string,node> mp;

vector<node> Nodes;

int main()
{
    scanf("%d %s",&n,head);

    for(int i=0; i<n; i++)
    {
        char address[6];
        char next[6];
        int key;
        scanf("%s %d %s",address,&key,next);
        mp[address]={address,key,next};
    }


    for(string i=head; i!="-1"; i=mp[i].next)
    {
        Nodes.push_back(mp[i]);
    }

    printf("%d",Nodes.size());

    if(Nodes.size()==0)
    {
        printf(" -1");     //注意 输出 格式
        return 0;
    }
    else
    {
        sort(Nodes.begin(),Nodes.end());
        printf(" %s\n",Nodes[0].address.c_str());
        for(int i=0; i<Nodes.size(); i++)
        {
            if(i+1==Nodes.size())
            {
                printf("%s %d -1\n",Nodes[i].address.c_str(),Nodes[i].key);
            }
            else
            {
                printf("%s %d %s\n",Nodes[i].address.c_str(),Nodes[i].key,Nodes[i+1].address.c_str());
            }
        }
    }

}

A1075


#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>

/*
        1.成绩为-2,表示从来没有提交过,则输出-
        2.成绩为-1,最后要输出0
*/

using namespace std;

const int K = 6;

int n, k, m;
int p_score[K];        //p_score[K]表示 各科成绩的 满分值

struct Student
{
    string id;
    int grade[K];         
    int total, cnt;

    Student(){}             //结构体的构造函数,
    Student(string _id) : id(_id)
    {
        for (int i = 1; i <= k; i ++ ) grade[i] = -2;     //所有的成绩 初始化为-2
        total = cnt = 0;            //总分和满分的题目个数设置为0
    }

    void calc()
    {
        for (int i = 1; i <= k; i ++ )
        {
            total += max(0, grade[i]);
            if (grade[i] == p_score[i]) cnt ++ ;
        }
    }

    bool has_submit()                  //根据例子对于0006就直接 返回false
    {
        for (int i = 1; i <= k; i ++ )
            if (grade[i] >= 0)
                return true;
        return false;
    }

    bool operator< (const Student& t) const
    {
        if (total != t.total) return total > t.total;               //按照总分的降序,满分答题数目的降序,id的升序进行排列
        if (cnt != t.cnt) return cnt > t.cnt;
        return id < t.id;
    }
};

int main()
{
    unordered_map<string, Student> students;          //设置一个map类型的 students

    scanf("%d%d%d", &n, &k, &m);                //输入n个人,k个成绩,m个提交结果
    for (int i = 1; i <= k; i ++ ) scanf("%d", &p_score[i]);         //输入各科的满分

    while (m -- )
    {
        string u_id;         //u_id为字符串
        char u_id_s[6];     //u_id_s为char数组
        int p_id, grade;          //p_id表示科目号,grade表示成绩
        scanf("%s%d%d", u_id_s, &p_id, &grade);
        u_id = u_id_s;

        //如果该同学u_id是在students中没有出现过,则定义studens中对应的u_id为一个新的 结构
        if (students.count(u_id) == 0) students[u_id] = Student(u_id);
        students[u_id].grade[p_id] = max(students[u_id].grade[p_id], grade);    //更新每个题目的 最高成绩
    }

    vector<Student> res;
    for (auto& item: students)           //用item去遍历 students
    {
        auto& s = item.second;          //s表示其中的结构体
        if (s.has_submit())            //如果为true,表示可以统计 该学生
        {
            s.calc();                 //计算总分和满分题目的个数
            res.push_back(s);
        }
    }

    sort(res.begin(), res.end());     //对res进行排序

    for (int i = 0, rank = 1; i < res.size(); i ++ )
    {
        if (i && res[i].total != res[i - 1].total) rank = i + 1;            //如果当前位置的人的 成绩和上一个人成绩不同,则排名为i+1

        printf("%d %s %d", rank, res[i].id.c_str(), res[i].total);      //输出 排名 id  总分

        for (int j = 1; j <= k; j ++ )          //j从1开始,一直到k
            if (res[i].grade[j] == -2) printf(" -");        //如果这个人的成绩为-2,则输出-
            else printf(" %d", max(0, res[i].grade[j]));        //否则,

        cout << endl;
    }

    return 0;
}


A1098

在这里插入图片描述


#include <iostream>

using namespace std;

const int N = 110;

int n;
int a[N], b[N];

void down(int u, int size)         //down(1,p-1)
{
    int t = u;
    if (u * 2 <= size && b[t] < b[u * 2]) t = u * 2;
    if (u * 2 + 1 <= size && b[t] < b[u * 2 + 1]) t = u * 2 + 1;
    if (t != u)
    {
        swap(b[t], b[u]);
        down(t, size);
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];     //给a数组输入值
    for (int i = 1; i <= n; i ++ ) cin >> b[i];     

    // 插入排序的思路是,第1个后面的值不大于前面的值
    int p = 2;
    while (p <= n && b[p] >= b[p - 1]) p ++ ;       //注意这里,对于插入排序,如果出现两个值相同,则继续向后走一位
    
    
    int k = p;
    while (p <= n && a[p] == b[p]) p ++ ;
    if (p == n + 1)  // 说明是插入排序
    {
        puts("Insertion Sort");
        while (k > 1 && b[k] < b[k - 1]) swap(b[k], b[k - 1]), k -- ;
    }
    else  // 否则说明一定是堆排序
    {
        puts("Heap Sort");
        p = n;
        while (b[1] <= b[p]) p -- ;
        swap(b[1], b[p]);
        down(1, p - 1);
    }

    cout << b[1];
    for (int i = 2; i <= n; i ++ ) cout << ' ' << b[i];
    cout << endl;

    return 0;
}

A1089

归并排序:先是两两分组,然后是44分组,然后是88分组,每次都是先将组内排好序

//注意从下标为0开始,所以数组下标写的时候也从0开始,同时这道题拿22分就行了,剩下3分不纠结
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int a[N], b[N];

bool check()
{
    for (int i = 0; i < n; i ++ )
        if (a[i] != b[i])
            return false;
    return true;
}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> a[i];
    for(int i=0; i<n; i++)
        cin >> b[i];

    int p=1;

    while(p<n && b[p]>b[p-1])
        p++;

    int k=p;

    while(p<n && b[p]==a[p])
        p++;

    if(p==n)
    {
        cout << "Insertion Sort" << endl;

        while(k>=0 && b[k]<b[k-1])
        {
             swap(b[k],b[k-1]);
            k--;
        }

        for(int i=0; i<n; i++)
        {
            if(i!=0)
                cout << " ";
            cout << b[i];
        }

        cout << endl;

    }
    else        //归并排序的整体思路就是模拟
    {
        puts("Merge Sort");

        int k = 1;
        while (true)
        {
            bool match = check();

            int len = 1 << k;  //
            for (int i = 0; i < n; i += len)
                sort(a + i, a + min(n, i + len));

            if (match) break;
            k ++ ;
        }

        cout << a[0];
        for (int i = 1; i < n; i ++ ) cout << ' '<< a[i];
        cout << endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值