大一寒假培训:结构体

痴心易碎 提交于 2020-01-22 23:24:54

一、结构体的定义与使用:

1.定义

在主函数内也可以在主函数外定义,下面是习惯用法:

struct student  //定义一个叫做“student”的结构体;
{  //以下是其中各种元素;
    char name[22];  
    char xuehao;  
    int age;  
    double mark;
}p[1001];  //给该结构体一个别名“p”,便于使用,且定义为一个结构体数组;

也可以这样:

#include <bits/stdc++.h>
using namespace std;
struct student
{
    char name[22];
    char xuehao;
    int age;
    double mark;
};  //此处不写;
int main()
{
    struct student p[1001];  //在主函数内进行声明,效果相同;
    return 0;
}

2.使用

*先补充一点sort函数的使用基础:

*再补充一点关于正则表达式“%[^\n]”:可用于需要输入带有空格的字符型数组(如英文名),这个表达式用于输入语句,如:

scanf("%[^\n]",&stu[i].name);  //意为输入直到键入回车(也就是\n)时停止输入;

还有一点很重要,不能在结构体声明中初始化结构体成员,因为结构体声明只是创建一个新的数据类型,还不存在这种类型的变量。例如,以下声明是非法的:

//非法结构体声明
struct Date
{
    int day = 23,
    month = 8,
    year = 1983;
}

因为结构体声明只声明一个结构体“看起来是什么样子的”,所以不会在内存中创建成员变量。只有通过定义该结构体类型的变量来实例化结构体,才有地方存储初始值。

我们通过一个题目来解释:NEFU OJ:谁考了第k名-排序

代码如下:

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

struct stu  //定义一个结构体;
{    char xuehao[10];  //学号,用字符型数组填数字时最好开大两格以上;
     double chengji;  //成绩
}p[105];  //别名为“p”,105个元素
bool cmp(stu a,stu b)  //定义一个比较方式,名为“cmp”
{
    return a.chengji>b.chengji;  //排序方式:"<"是升序,">"是降序(可以记箭头方向)
}
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++)
        {getchar();  //这里注意使用getchar来防止回车被写入xuehao字符串;
         scanf("%s %lf",&p[i].xuehao,&p[i].chengji);} 
    sort(p,p+n,cmp);  //sort的使用:sort(起始地址,最后一个元素的下一个地址,自定义比较函数(可以不填));
                      //sort默认升序排序,可以用less换成降序排序;
    printf("%s %g",p[k-1].xuehao,p[k-1].chengji);
    return 0;
}

初学者在使用中要注意,在循环中使用结构体内变量时,格式为:“别名[循环变量]”.“变量名”,不要忘了循环变量。

二、结构体专题练习&题解

1.NEFU OJ:奇数单增序列

//这题比较简单,没什么好说的;
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int str[n];
    for(int i=0;i<n;i++)
        cin>>str[i];
    int str1[n],k=0;
    for(int i=0;i<n;i++)
    {
        if(str[i]%2!=0)
        {
            str1[k]=str[i];
            k++;
        }
    }
    sort(str1,str1+k);
    for(int i=0;i<k;i++)
    {
        if(i!=k-1)
            cout<<str1[i]<<",";
        else
            cout<<str1[i];
    }
    return 0;
}

2.NEFU OJ:成绩排序

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

struct stu
{
    char name[22];
    int grade;
}p[30];
bool cmp(stu a,stu b)
{
    if(a.grade!=b.grade)
    return a.grade>b.grade;
    else
        return a.name<b.name;
}
int main()
{
    int n;  cin>>n;
    for(int i=0;i<n;i++)
        {getchar();
        scanf("%s %d",&p[i].name,&p[i].grade);}
    sort(p,p+n,cmp);
    for(int i=0;i<n;i++)
        cout<<p[i].name<<" "<<p[i].grade<<endl;
    return 0;
}

3.NEFU OJ:没必要的排序2

//这题要注意,排序会超时,得用桶排序
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n,k,x,ans=0,y=0;
    cin>>n>>k;
    int t[100001]={0};  //定义一个“桶子”;
    for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            t[x]++;  //输入该数,则在该桶位加1;
        }
    for(int i=100000;i>=1;i--)
    {
        if(t[i]>0)
        {
            ans=ans+t[i]*i;  //加和;
            y=y+t[i];
        }
        if(y>k)  
        {
            ans=ans-(y-k)*i;  //减去加多了的数;
            break;
        }
    }
    cout<<ans;
    return 0;
}

4.NEFU OJ:老和尚的导员

//没啥好说的;
#include <bits/stdc++.h>
using namespace std;

struct hs
{
    int num;
    int cyy;
    int xd;
    int gs;
    int yy;
    int all;
}ren[101];
bool cmp(hs a,hs b)
{
    if(a.all!=b.all)
        return a.all>b.all;
    else
    {
        if(a.cyy!=b.cyy)
            return a.cyy>b.cyy;
        else if(a.xd!=b.xd)
            return a.xd>b.xd;
        else if(a.gs!=b.gs)
            return a.gs>b.gs;
        else if(a.yy!=b.yy)
            return a.yy>b.yy;
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {for(int i=1;i<=n;i++)
    {
        ren[i].num=i;
        scanf("%d %d %d %d",&ren[i].cyy,&ren[i].xd,&ren[i].gs,&ren[i].yy);
        ren[i].all=ren[i].cyy+ren[i].xd+ren[i].gs+ren[i].yy;
    }
    sort(ren+1,ren+n+1,cmp);
    for(int i=1;i<=n;i++)
        cout<<ren[i].num<<" "<<ren[i].all<<endl;}
    return 0;
}

5.NEFU OJ:健忘的老和尚

这题注意:无论是奖励还是惩罚**按照总成绩从低到高输出**和尚的名字即可。

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

struct hs
{
   char name[110];
   int all;
}ren[300];
bool cmp(hs a,hs b)
{
    return a.all>b.all;
}
int main()
{
    int n,m,s;
    while(~scanf("%d %d %d",&n,&m,&s))
    {
        for(int i=0;i<n;i++)
           {getchar();scanf("%s%d",&ren[i].name,&ren[i].all);}
        sort(ren,ren+n,cmp);
        for(int i=m-1;i>=0;i--)
            cout<<ren[i].name<<endl;
        for(int i=n-1;i>=n-s;i--)
            cout<<ren[i].name<<endl;
    }
    return 0;
}

6.NEFU OJ:戏说三国

看清楚题目再写!!!智育、德育、武育三个分数,分别以**b%,a%,c%**的比率计入加权总分,不是abc!!!罚时一次20min!

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

struct sg
{
   char name[30];
   double zy,dy,wy,all;
}x[1001];
bool cmp(sg a,sg b)
{
    if(a.all!=b.all)  return a.all>b.all;
    else if(a.zy!=b.zy)  return a.zy>b.zy;
    else if(a.dy!=b.dy)  return a.dy>b.dy;
    else if(a.wy!=b.wy)  return a.wy>b.wy;
}
int main()
{
    int m,r=0;  cin>>m;
    while(m--)
    {
        int n;  double a,b,c;
        cin>>n>>a>>b>>c;
        a=a/100;  b=b/100;  c=c/100;
        for(int i=0;i<n;i++)
        {getchar();scanf("%s %lf %lf %lf",&x[i].name,&x[i].zy,&x[i].dy,&x[i].wy);
         x[i].all=x[i].zy*b+x[i].dy*a+x[i].wy*c;
         x[i].zy=x[i].zy*b;
         x[i].dy=x[i].dy*a;
         x[i].wy=x[i].wy*c;}
        sort(x,x+n,cmp);
        r++;
        cout<<"Case #"<<r<<":"<<endl;
        for(int i=0;i<n;i++)
            printf("%s %.4lf %.4lf %.4lf %.4lf\n",x[i].name,x[i].all,x[i].zy,x[i].dy,x[i].wy);
    }
    return 0;
}

7.NEFU OJ:相约摩洛哥

多组输入一定要注意累加变量的清零!!

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

struct sg
{
   char name[12];
   int t1,t2,t3;
   int c1,c2,c3;
   int all,ac;  //all和ac变量在每次运行后一定要记得清零!
}x[100001];
bool cmp(sg a,sg b)
{
    if(a.ac!=b.ac)  return a.ac>b.ac;
    if(a.ac==b.ac)  return a.all<b.all;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
            {getchar();
             scanf("%s %d %d %d",&x[i].name,&x[i].t1,&x[i].t2,&x[i].t3);}
        for(int i=0;i<n;i++)
            cin>>x[i].c1>>x[i].c2>>x[i].c3;
        for(int i=0;i<n;i++)
        {
            if(x[i].t1!=-1)  {x[i].all=x[i].all+x[i].t1+(x[i].c1-1)*20;  x[i].ac++;}
            if(x[i].t2!=-1)  {x[i].all=x[i].all+x[i].t2+(x[i].c2-1)*20;  x[i].ac++;}
            if(x[i].t3!=-1)  {x[i].all=x[i].all+x[i].t3+(x[i].c3-1)*20;  x[i].ac++;}
        }
        sort(x,x+n,cmp);
        for(int i=0;i<n;i++)
            {printf("%s %d %d\n",x[i].name,x[i].ac,x[i].all);
        x[i].all=0; x[i].ac=0;} //清零操作;
    }
    return 0;
}

8.NEFU OJ:结构体排序题一

这题要在主函数内进行多次排序,我尝试过把t1,t2赋值到结构体内用选择语句在bool函数内进行比较,但不知道由于什么原因致使输出结果与答案完全相反。

#include <bits/stdc++.h>
using namespace std;
struct px
{
    int x,y;
}p[1001];
bool cmp1(px a,px b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x<b.x;
}
bool cmp2(px a,px b)
{
    if(a.x==b.x) return a.y>b.y;
    else return a.x<b.x;
}
bool cmp3(px a,px b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x>b.x;
}
bool cmp4(px a,px b)
{
    if(a.x==b.x) return a.y>b.y;
    else return a.x>b.x;
}
int main()
{
    int n,i,t1,t2;
    while(~scanf("%d%d%d",&t1,&t2,&n))
    {
        for(i=1;i<=n;i++)
        scanf("%d %d",&p[i].x,&p[i].y);
        //四种情况,分四种sort即可;
        if(t1==1&&t2==1)sort(p+1,p+n+1,cmp1);
        if(t1==1&&t2==0)sort(p+1,p+n+1,cmp2);
        if(t1==0&&t2==1)sort(p+1,p+n+1,cmp3);
        if(t1==0&&t2==0)sort(p+1,p+n+1,cmp4);
        for(i=1;i<=n;i++)
        printf("(%d,%d)\n",p[i].x,p[i].y);
    }
    return 0;
}

于2020年1月1日元旦,大一寒假培训第二天,编辑。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!