ACM寒假训练第二周总结

时间:2022.1.17——2022.1.23


一、刷题记录

1. P1271 【深基9.例1】选举学生会

using namespace std;
int a[1005]={0};
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x;
        cin>>x;
        a[x]++;
    }
    for(int i=1;i<=n;i++){
        while(a[i]){
            cout<<i<<' ';
            a[i]--;
        }
    }
    return 0;
}

 

2. P1177 【模板】快速排序        本题使用传统的快排会出现TLE,将二分法查找应用进去就可以加快程序的运行。

#include "iostream"
using namespace std;
int a[100000];
void quickSort(int left,int right)
{
    int i=left,j=right;
    int basic=a[(i+j)/2];
    while(i<=j){
        for(;a[j]>basic;j--);
        for(;a[i]<basic;i++);
        if(i<=j){
            swap(a[i],a[j]);    i++;    j--;
        }
    }
    if(left<j) quickSort(left,j);
    if(i<right) quickSort(i,right);
}

int main()
{
    int N;
    cin>>N;
    for(int i=0;i<N;i++){
        cin>>a[i];
    }
    quickSort(0,N-1);
    for(int i=0;i<N;i++)
        cout<<a[i]<<' ';
    cout<<endl;
    return 0;
}

 

3. P1923 【深基9.例4】求第 k 小的数        这道题依旧采用二分快排,再判断k值与基准值的位置关系,选择性的排序,减少程序的运行时间。但是这样的话依旧会出现一个TLE,于是我发现scanf和printf的运行速度是比cin与cout的运行速度是快。全部换成scanf和printf就可以AC了。

#include "iostream"
using namespace std;
long a[5000005];
int k;
void quickSort(int left,int right)
{
    int i=left,j=right;
    long basic=a[(i+j)/2];
    while(i<=j){
        for(;a[j]>basic;j--);
        for(;a[i]<basic;i++);
        if(i<=j){
            swap(a[i],a[j]);    i++;    j--;
        }
    }
    if(k<=j)    quickSort(left,j);
    else if(k>=i)   quickSort(i,right);
    else{
        printf("%ld",a[j+1]);
        exit (0);
    }
}

int main()
{
    int N;
    scanf("%d %d",&N,&k);
    for(int i=0;i<N;i++){
        scanf("%ld",&a[i]);
    }
    quickSort(0,N-1);
}

 

4. P1059 [NOIP2006 普及组] 明明的随机数        这题无难度,直接“对号入座”再判断输出即可。

#include "iostream"
using namespace std;
int a[1005];
int main()
{
    int N,M=0;
    cin>>N;
    while(N--){
        int x;
        cin>>x;
        if(a[x]==0){    a[x]=1; M++;    }
    }
    cout<<M<<endl;
    for(int i=1; i<=1000; i++){
        if(a[i]==1)
            cout<<i<<' ';
    }
    cout<<endl;
    return 0;
}

 

5. P1093 [NOIP2007 普及组] 奖学金        这题直接使用algorithm库函数下sort函数对数组进行条件排序即可。

#include "iostream"
#include "algorithm"
using namespace std;
struct student{
    int num,ach,chinese;
}stu[301];
bool sort2(student x,student y){
    if(x.ach!=y.ach)    return (x.ach>y.ach);
    if(x.chinese!=y.chinese)    return (x.chinese>y.chinese);
    if(x.num!=y.num)    return (x.num<y.num);
    return 0;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int a,b,c;
        cin>>a>>b>>c;
        stu[i].num=i;     stu[i].ach=a+b+c;     stu[i].chinese=a;
    }
    sort(stu+1,stu+n+1,sort2);
    for(int i=1;i<=5;i++)
        cout<<stu[i].num<<' '<<stu[i].ach<<endl;
    return 0;
}

 

6. P1781 宇宙总统        因为票数的数据可能达到100位,所以创建一个结构体变量将票数定义为string型,依旧使用sort函数。

#include "iostream"
#include "algorithm"
using namespace std;
struct people{
    string s;
    int num;
}a[21];
bool sort2(people x,people y)
{
    if(x.s==y.s)    return true;
    else if((x.s).length()!=(y.s).length()) return x.s.length()>y.s.length();
    else return x.s>y.s;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        a[i].num=i;
        cin>>a[i].s;
    }
    sort(a+1,a+n+1,sort2);
    cout<<a[1].num<<endl<<a[1].s<<endl;

    return 0;
}

 

7. P2676 [USACO07DEC]Bookshelf B        

#include "iostream"
#include "algorithm"
using namespace std;
int a[20005];
bool sort2(int a1,int a2)
{
    return a1>a2;
}
int main()
{
    int N,B,sum=0;
    cin>>N>>B;
    for(int i=1;i<=N;i++)
        cin>>a[i];
    sort(a+1,a+N+1,sort2);
    int i=1;
    while(sum<B){
        sum+=a[i];
        i++;        }
    cout<<i-1<<endl;
    return 0;
}

 

8. P1116 车厢重组        只能相邻数据俩俩交换,简单的冒泡法就可以实现。(其实并不需要排序,仅统计次数就可以了)

#include "iostream"
using namespace std;
int a[1000];
int main()
{
    int N,sum=0;
    cin>>N;
    for(int i=0;i<N;i++)
        cin>>a[i];
    for(int i=0;i<N;i++)
        for(int j=i+1;j<N;j++)
            if(a[i]>a[j])   sum++;
    cout<<sum<<endl;
    return 0;
}

 

9. P1152 欢乐的跳        这一题我们可以建一个数组b[],用来存放a[]数据中两相邻数的差出现的次数,因为n个数据必定有n-1个相邻数的差,所以我最后只需要统计b数组中所有数据出现的次数的总和sum,看sum是否等于n-1即可。

#include "iostream"
using namespace std;
int a[1001],b[1000]={0};
int main()
{
    int n,sum=0;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<n;i++){
        int t=abs(a[i]-a[i+1]);
        if(0<t&&t<=(n-1))
            b[t]++;
    }
    for(int i=1;i<1000;i++)
        sum+=b[i];
    if(sum==(n-1))  cout<<"Jolly"<<endl;
    else    cout<<"Not jolly"<<endl;
    return 0;
}

 

10. P1068 [NOIP2009 普及组] 分数线划定        这一题并不难 看清题目很容易AC

#include "iostream"
#include "algorithm"
using namespace std;
struct exam{
    int num;
    int f;
} a[50001];
bool sort2(exam x,exam y)
{
    if(x.f!=y.f)  return x.f>y.f;
    else    return x.num<y.num;
}
int main()
{
    int n,m,i;
    cin>>n>>m;
    for(i=1;i<=n;i++){
        cin>>a[i].num>>a[i].f;
    }
    sort(a+1,a+n+1,sort2);
    m=m*1.5;
    for(i=1;a[i].f>=a[m].f&&i<=n;i++);
    cout<<a[m].f<<' '<<i-1<<endl;
    for(i=1;a[i].f>=a[m].f&&i<=n;i++)
        cout<<a[i].num<<' '<<a[i].f<<endl;
    return 0;
}

 

11. P5143 攀爬者        

#include "iostream"
#include "algorithm"
#include "math.h"
using namespace std;
struct xyz{
    int x,z,y;
}a[50001];
bool sort2(xyz n,xyz m){
    return (n.z<m.z);
}
int main()
{
    int N;
    double f=0;
    cin>>N;
    for(int i=1;i<=N;i++){
        cin>>a[i].x>>a[i].y>>a[i].z;
    }
    sort(a+1,a+N+1,sort2);
    for(int i=1;i<N;i++)
        f+=sqrt(pow(a[i].x-a[i+1].x,2)+pow(a[i].y-a[i+1].y,2)+pow(a[i].z-a[i+1].z,2));
    printf("%.3lf
",f);
    return 0;
}

 

12. P1104 生日

#include "iostream"
#include "algorithm"
using namespace std;
struct stu{
    string name;
    int y,m,d,num;
}a[100];
bool sort2(stu x,stu y){
    if(x.y!=y.y)    return x.y<y.y;
    else if(x.m!=y.m)   return x.m<y.m;
    else if(x.d!=y.d)   return x.d<y.d;
    else return x.num>y.num;
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i].name>>a[i].y>>a[i].m>>a[i].d;
        a[i].num=i;
    }
    sort(a,a+n,sort2);
    for(int i=0;i<n;i++)
        cout<<a[i].name<<endl;
    return 0;
}

 

13. P1012 [NOIP1998 提高组] 拼数        这一题按照以前sort函数写return x>y; 的话最后会有一个WA,因为输入数据类型为string,当输入321   32   1这组数据时,return x>y;会判定321>32,即结果为:321321,显然是不对的,所以使用return x+y>y+x;这样的话就会整体判断32132与32321的大小,就不会出错了。

#include "iostream"
#include "algorithm"
using namespace std;
string a[20];
bool sort2(string x,string y){
    return x+y>y+x;
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n,sort2);
    for(int i=0;i<n;i++)
        cout<<a[i];
    cout<<endl;
    return 0;
}

二、个人总结

1. 经过这一周的训练,我已经基本会使用sort函数与快排了,虽然会使函数更简便,但也并没有快排的运行速度快,所以有时候还是要选择性的使用各种函数与算法。

2. 本周整体来说并不是很难的,所以刷完之后对于排序的各种算法和函数还需要找更多的题目来巩固。

3. 对于部分的题即使是用了算法也可能会TLE,所以对传统算法也需要进行优化。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM程序设计竞赛基础教程(第2版)》是一本经典的程序设计竞赛教材,旨在帮助学习者掌握ACM程序设计竞赛的基础知识和解题技巧。 该教材以清晰简明的语言详细介绍了ACM竞赛所需的基本知识,包括数据结构、算法设计与分析、动态规划、图论等。同时,它提供了大量的例题和习题,帮助学习者巩固知识,培养解题能力。 与其他类似的教材相比,这本教材具有以下几个特点: 首先,该教材内容全面,不仅介绍了ACM竞赛中常见的基础知识,还涵盖了一些高级内容。通过学习这本教材,学习者能够建立起扎实的程序设计基础,为进一步深入学习和应用打下坚实的基础。 其次,该教材注重实战,提供了大量的例题和习题。这些题目都是经过精心挑选和设计的,能够帮助学习者理解和掌握各种解题技巧。通过反复练习,学习者能够逐渐提高自己的编程水平和解题能力。 最后,该教材配有详细的讲解和解答,帮助学习者更好地理解和掌握知识点。无论是初学者还是有一定基础的学习者,都可以根据自己的情况选择性地学习和提升。 《ACM程序设计竞赛基础教程(第2版)》是一本值得推荐的优秀教材,它不仅适用于参加ACM竞赛的学生,也适用于对算法和程序设计感兴趣的人。通过学习这本教材,学习者能够提高自己的编程能力,锻炼解决问题的思维方式,为将来的学习和工作打下良好的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值