pta甲级1167+1015+1014+1012

1167:https://pintia.cn/problem-sets/994805342720868352/exam/problems/1478636026017230848

是一道裸题笛卡尔树,笛卡尔树具有键值和权值两个衡量标尺,键值满足complete tree,权值满足大(小)根堆的性质;并且通过inorder可以得到原序列;

对于这道题来讲,按照小根堆的性质建好这颗树就可以进行bfs了;

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<queue>
 6 using namespace std;
 7 vector<int>ans;
 8 struct node
 9 {
10     int data;
11     node *lc;
12     node *rc;
13     node(int data=0,node *lc=NULL,node *rc=NULL):data(data),lc(lc),rc(rc){}
14 };
15 int n;
16 int a[50];
17 node *build_tree(int l,int r)
18 {
19     if(l>r)
20         return NULL;
21     node *root=new node();
22     int pos=0;
23     int k=0x3f3f3f3f;
24     for(int i=l;i<=r;i++)
25     {
26         if(a[i]<k)
27         {
28             pos=i;
29             k=a[i];
30         }
31     }
32     root->data=a[pos];
33     root->lc=build_tree(l,pos-1);
34     root->rc=build_tree(pos+1,r);
35     return root;
36 }
37 void bfs(node *root)
38 {
39     queue<node*>q;
40     q.push(root);
41     while(!q.empty())
42     {
43         node *t=q.front();
44         q.pop();
45         ans.push_back(t->data);
46         if(t->lc)
47             q.push(t->lc);
48         if(t->rc)
49             q.push(t->rc);
50     }
51 
52 }
53 int main()
54 {
55     cin>>n;
56     for(int i=1;i<=n;i++)
57     {
58         cin>>a[i];
59     }
60     node *root=build_tree(1,n);
61     bfs(root);
62     for(int i=0;i<ans.size();i++)
63     {
64         cout<<ans[i];
65         if(i<ans.size()-1)
66         {
67             cout<<" ";
68         }
69     }
70     return 0;
71 }

1015:https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805495863296000

题目要求满足一个数在n进制状态下满足是素数,并且对于这个数的回文数来讲也要满足素数

所以说先求这个数是不是素数,之后在判断他的回文数是否是素数就可以了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long 
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 int n,r;
 6 vector<int>num;
 7 bool is_pirme(int x)
 8 {
 9     if(x<=1)
10     return false;
11     for(int i=2;i<=sqrt(x);i++)
12     {
13         if(x%i==0)
14         return false;
15     }
16     return true;
17 }
18 signed main()
19 {
20     IOS;
21     while(cin>>n>>r)
22     {
23         num.clear();
24         if(n<0)
25         break;
26         if(!is_pirme(n))
27         {
28             cout<<"No"<<endl;
29         }
30         else
31         {
32             while(n>0)
33             {
34                     num.push_back(n%r);
35                     n=n/r;
36             }
37             for(int i=0;i<num.size();i++)
38             {
39                 n=n*r+num[i];
40             }
41             if(is_pirme(n))
42             {
43                 cout<<"Yes"<<endl;
44             }
45             else
46             {
47                 cout<<"No"<<endl;
48             }
49         }
50     }
51     return 0;
52     
53 }

1012:https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805502658068480

比较复杂的一道模拟题,学习的晴神的代码,感觉比之前优化了许多,

题目讲给出一个学生的id,c语言成绩,数学成绩,英语成绩,然后潜规则求出平均成绩,然后给出这个学生的排名

但排名的大小也有规则,规则是求出最好成绩的排名,就比如说,c语言||数学||英语排第一那排名就是第一

或者是平均成绩第一那排名也是第一;

并且对于最好排名的规则顺序是:平均>c>数学>英语

做法则是在结构体中用g[4】来表示a,c,m,e的成绩,用rank[id][g[x]]来表示学号为id的学生的g[x]成绩的排名,当然排序也用了优化:

根据a>c>m>e的规则将个人成绩排序起来;

在将当前成绩和后一名同学的成绩作比较,如果相同则两人的成绩相同,如不然则是按照顺序j+1就ok了;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long 
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int N=2010;
 6 struct node
 7 {
 8     int id;
 9     int g[5];//从0~4分别表示平均,c,数学,英语成绩
10 }stu[N];
11 int n,m;
12 char sub[5]={'A','C','M','E'};//表示4课
13 int now;
14 int Rank[1000010][4];//学号为id的学生的第g[x]门成绩的排名
15 bool cmp(node x,node y)
16 {
17     return x.g[now]>y.g[now];//按照a>c>m>e的顺序将个人成绩进行排名
18 }
19 signed main()
20 {
21     IOS;
22     cin>>n>>m;
23     for(int i=0;i<n;i++)
24     {
25         cin>>stu[i].id>>stu[i].g[1]>>stu[i].g[2]>>stu[i].g[3];
26         stu[i].g[0]=(stu[i].g[1]+stu[i].g[2]+stu[i].g[3])/3;
27     }
28     for(now=0;now<4;now++)//枚举当前的4门成绩
29     {
30         sort(stu,stu+n,cmp);
31         Rank[stu[0].id][now]=1;//将当前排完序的学生的当前成绩列为第一
32         for(int j=1;j<n;j++)
33         {
34             if(stu[j].g[now]==stu[j-1].g[now])
35             {//如果是出现这个学生的成绩和后一名学生的成绩相同
36                 Rank[stu[j].id][now]=Rank[stu[j-1].id][now];//二者成绩相同
37             }
38             else
39             {
40                 Rank[stu[j].id][now]=j+1;//如不然则是按照顺序递增
41             }
42         }
43     }
44     int q;
45     for(int i=0;i<m;i++)
46     {
47         cin>>q;
48         if(Rank[q][0]==0)//这个学生的平均成绩是0就没有这个学生
49         {
50             cout<<"N/A";
51         }
52         else
53         {
54             int k=0;
55             for(int j=0;j<4;j++)
56             {
57                 if(Rank[q][j]<Rank[q][k])
58                 {
59                     k=j;//找最小的(最好的成绩)
60                 }
61             }
62             cout<<Rank[q][k]<<" "<<sub[k];
63         }
64         if(i<m-1)
65         cout<<endl;
66     }
67     return 0;
68 }

1014:https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805498207911936

比较难处理的模拟题;

题目给定的模型是银行排队,我比较推荐这篇博客:https://blog.csdn.net/weixin_55202895/article/details/125638852?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166480391316782414922428%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166480391316782414922428&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-125638852-null-null.142^v51^pc_rank_34_queryrelevant25,201^v3^control_1&utm_term=1014%20Waiting%20in%20Line&spm=1018.2226.3001.4187(转载)

讲的比较详细,可以学习一下这个大神的思路

 

posted @ 2022-10-03 21:32  江上舟摇  阅读(33)  评论(0编辑  收藏  举报