目录

!L2-001 城市间紧急救援 - Dijkstra运用

!L2-002 链表去重 - 链表模拟

!L2-003 月饼 - 结构体+重载运算符+排序

!L2-004 这是二叉搜索树吗?- 建二叉树模板题

L2-005 集合相似度 - set容器去重应用

L2-006 树的遍历 - 中后序遍历构建树+层序遍历

!L2-007 家庭房产 - 并查集+结构体+排

!L2-008 最长对称子串 - 字符串+暴力+双指

getline和cin区别

L2-009 抢红包 - 模拟+排序

L2-010 排座位

L2-011 玩转二叉树 - 前中序遍历构建树+层序遍历

✓L2-012 关于堆的判断 - 优先队列+哈希表


!L2-001 城市间紧急救援 - Dijkstra运用

思路:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;const int N=510;
int n,m,s,d;
int g[N][N];
int dist[N],w[N],sumw[N],road[N],pre[N];
int prt[N],cnt=0;
bool st[N];void dijkstra()
{memset(dist,0x3f,sizeof dist);dist[s]=0;sumw[s]=w[s]; //救援队数目road[s]=1; //最短路径的条数 for(int i=0;i<n;i++){int t=-1;for(int j=0;j<n;j++)if(!st[j]&&(t==-1||dist[j]<dist[t]))t=j;st[t]=true;for(int j=0;j<n;j++){if(dist[j]>dist[t]+g[t][j]) //选最短路径{dist[j]=dist[t]+g[t][j];road[j]=road[t]; //不理解sumw[j]=sumw[t]+w[j];pre[j]=t;}else if(dist[j]==dist[t]+g[t][j]){road[j]+=road[t]; //不理解if(sumw[j]<sumw[t]+w[j]){sumw[j]=sumw[t]+w[j];pre[j]=t;}}} }cout<<road[d]<<' '<<sumw[d]<<endl;//把经过的点倒序输出 cout<<s;for(int i=d;i!=s;i=pre[i])prt[cnt++]=i;reverse(prt,prt+cnt);for(int i=0;i<cnt;i++)cout<<' '<<prt[i];
}int main()
{cin>>n>>m>>s>>d;for(int i=0;i<n;i++) cin>>w[i];memset(g,0x3f,sizeof g);while(m--){int a,b,c;cin>>a>>b>>c;g[a][b]=g[b][a]=c;}dijkstra();return 0;
}

!L2-002 链表去重 - 链表模拟

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;const int N=1e5+10;
int head,n;
int e[N],ne[N];
bool st[N];int main()
{cin>>head>>n;while(n--){int idx,w,next;cin>>idx>>w>>next;e[idx]=w,ne[idx]=next;}vector<int>re,unre; //re存重复元素 unre存不重复元素 for(int i=head;i!=-1;i=ne[i]){int x=abs(e[i]);if(!st[x]){st[x]=true;unre.push_back(i);}else re.push_back(i);}//输出去重的链表 for(int i=0;i<unre.size();i++){printf("%05d %d",unre[i],e[unre[i]]);if(i==unre.size()-1) puts(" -1");else printf(" %05d\n",unre[i+1]);} //输出删去的链表 for(int i=0;i<re.size();i++){printf("%05d %d",re[i],e[re[i]]);if(i==re.size()-1) puts(" -1");else printf(" %05d\n",re[i+1]);} return 0;
}

!L2-003 月饼 - 结构体+重载运算符+排序

思路:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;const int N=1010;
int n;
double d,res=0;
struct node
{double w,p;bool operator<(const node &t)const //按照单价由大到小排序{return p/w>t.p/t.w; }
}a[N];int main()
{cin>>n>>d;for(int i=0;i<n;i++) cin>>a[i].w;for(int i=0;i<n;i++) cin>>a[i].p;sort(a,a+n);for(int i=0;i<n&&d>0;i++){if(a[i].w<=d){d-=a[i].w;res+=a[i].p;}else{res+=a[i].p/a[i].w*d;break;}//这个办法很妙↓/*double r=min(d,a[i].w);d-=r;res+=a[i].p/a[i].w*r;*/}printf("%.2f\n",res);return 0;
}

!L2-004 这是二叉搜索树吗?- 建二叉树模板题

思路:

#include <iostream>
#include <malloc.h>
using namespace std;const int N=1010;
int n,a[N];
int p1[N],p2[N];
int cnt1=0,cnt2=0;
bool flag;typedef struct node
{int data;node *l,*r;
}node,*tree;tree create1(tree T,int x)
{if(!T) {T=(tree)malloc(sizeof(node));T->l=nullptr,T->r=nullptr;T->data=x;}else{if(T->data>x) T->l=create1(T->l,x);else if(T->data<=x) T->r=create1(T->r,x);}return T;
}tree create2(tree T,int x)
{if(!T) {T=(tree)malloc(sizeof(node));T->l=nullptr,T->r=nullptr;T->data=x;}else{if(T->data<=x) T->l=create2(T->l,x);else if(T->data>x) T->r=create2(T->r,x);}return T;
}void pre1(tree T)
{if(!T) return;p1[cnt1++]=T->data;pre1(T->l);pre1(T->r);
} void pre2(tree T)
{if(!T) return;p2[cnt2++]=T->data;pre2(T->l);pre2(T->r);
} void post(tree T)
{if(!T) return;post(T->l);post(T->r);if(flag) cout<<' ';flag=true;cout<<T->data;
}int main()
{cin>>n;for(int i=0;i<n;i++) cin>>a[i];//创建二叉搜索树 tree T1=nullptr;for(int i=0;i<n;i++) T1=create1(T1,a[i]);//创建镜像二叉搜索树tree T2=nullptr;for(int i=0;i<n;i++) T2=create2(T2,a[i]);//分非镜像和镜像进行前序遍历  和原序列进行比较  pre1(T1),pre2(T2);bool f1=false,f2=false;for(int i=0;i<n;i++) if(p1[i]!=a[i]) f1=true;for(int i=0;i<n;i++) if(p2[i]!=a[i]) f2=true;if(f1&&f2) cout<<"NO";else if(!f1&&f2) puts("YES"),post(T1);else if(f1&&!f2) puts("YES"),post(T2);else if(!f1&&!f2) puts("YES"),post(T1);return 0;
}

L2-005 集合相似度 - set容器去重应用

#include <iostream>
#include <set>
using namespace std;const int N=1e4+10;
int n,m,k;int main()
{set<int>s[N];cin>>n;for(int i=1;i<=n;i++){cin>>m;while(m--){int x;cin>>x;s[i].insert(x);}}cin>>k;while(k--){int a,b,cnt=0;cin>>a>>b;for(auto x:s[a]) if(s[b].count(x)) cnt++;printf("%.2f%%\n",cnt*1.0/(s[a].size()+s[b].size()-cnt)*100);}return 0;
}

L2-006 树的遍历 - 中后序遍历构建树+层序遍历

思路: 这题思路跟L2-011 玩转二叉树一模一样啊 就是板子题

  • 通过中后序构建树
  • 层序遍历
#include <iostream>
#include <malloc.h>
#include <queue>
using namespace std;const int N=35;
int n;
int po[N],mid[N];typedef struct node
{int data;node *l,*r;
}node,*tree;tree reback(int len,int *po,int *mid) //通过中序和后序遍历还原前序遍历
{if(len<=0) return NULL;tree T=(tree)malloc(sizeof(node));T->l=T->r=NULL;T->data=po[len-1]; //后序遍历的最后一个点为前序遍历根节点int i=0; for(i=0;i<len;i++)if(T->data==mid[i]) break; //在中序遍历里找到树根 记录i T->l=reback(i,po,mid);T->r=reback(len-1-i,po+i,mid+i+1);return T;
}void bfs(tree T)
{bool flag=false;queue<tree>q;q.push(T);while(q.size()){auto t=q.front();q.pop();if(flag) cout<<' ';flag=true;cout<<t->data;if(t->l)q.push(t->l);if(t->r)q.push(t->r);}
}int main()
{cin>>n;for(int i=0;i<n;i++) cin>>po[i];for(int i=0;i<n;i++) cin>>mid[i];tree T=reback(n,po,mid);bfs(T);return 0;
}

!L2-007 家庭房产 - 并查集+结构体+排

#include <bits/stdc++.h>
using namespace std;const int N=1e5+10;
int n;
int f[N];
map<int,bool>st;struct peo
{int id;double cnt,area;
}p[N];struct family
{int anc=-1,num;double cnt,area,avg_cnt,avg_area;
}fam[N];int find(int x)
{if(x!=f[x]) f[x]=find(f[x]);return f[x];
}void unite(int a,int b)
{int x=find(a);int y=find(b);if(x!=y) f[x]=y;
}bool cmp(family a,family b) //家庭信息首先按人均面积降序输出,若有并列,则按成员编号的升序输出。
{if(a.avg_area!=b.avg_area)return a.avg_area>b.avg_area;else return a.anc<b.anc;
}int main()
{for(int i=0;i<N;i++) f[i]=i;cin>>n;for(int i=0;i<n;i++){int id,fa,ma;cin>>id>>fa>>ma;st[id]=true;if(fa!=-1) st[fa]=true,unite(id,fa);if(ma!=-1) st[ma]=true,unite(id,ma);int k;cin>>k;while(k--){int x;cin>>x;unite(x,id);st[x]=true;}int cnt,area;cin>>cnt>>area;p[id].cnt=cnt,p[id].area=area;}for(auto x:st){fam[find(x.first)].cnt+=p[x.first].cnt;fam[find(x.first)].area+=p[x.first].area;if(fam[find(x.first)].anc==-1) fam[find(x.first)].anc=x.first;fam[find(x.first)].num++;}for(int i=0;i<N;i++){if(!st[i])continue;fam[find(i)].avg_cnt=fam[find(i)].cnt/fam[find(i)].num;fam[find(i)].avg_area=fam[find(i)].area/fam[find(i)].num;}int sum=0;for(int i=0;i<N;i++) if(fam[i].num) sum++;cout<<sum<<endl;sort(fam,fam+N,cmp);for(int i=0;i<sum;i++)printf("%04d %d %.3f %.3f\n",fam[i].anc,fam[i].num,fam[i].avg_cnt,fam[i].avg_area);return 0;
}

!L2-008 最长对称子串 - 字符串+暴力+双指

getline和cin区别

getline——按行读取, 一次读取多个字符,直到读满N个(不包括空白符)为止。
形式:getline(字符指针,字符个数N,结束符);

cin——遇到结束符(包括空白符)会终止,只读取空白符之前的部分。

#include <bits/stdc++.h>
using namespace std;const int N=1e5+10;int main()
{int res=0;string s;getline(cin,s); //不能用cin cin遇到空格就截止for(int i=0;i<s.size();i++)for(int j=s.size()-1;j>=i;j--){int l=i,r=j;while(l<=r&&s[l++]==s[r--])if(l>r) res=max(res,j-i+1);}cout<<res<<endl;return 0;
}
#include <bits/stdc++.h>
using namespace std;
string s;
int main()
{getline(cin,s);for(int len=s.size();len>0;len--) //找最大长度 倒序找for(int l=0;l+len-1<s.size();l++){bool f=false;int i=l,j=l+len-1;while(i<j){if(s[i]!=s[j]){f=true;break;}i++,j--;}if(!f){cout<<len<<endl;return 0;}}
}

L2-009 抢红包 - 模拟+排序

思路:

#include <bits/stdc++.h>
using namespace std;const int N=1e4+10;struct node
{int id;double qiang_w,fa_w,res;int qiang_count;
}a[N];bool cmp(node a,node b)
{if(a.res!=b.res) return a.res>b.res;else if(a.qiang_count!=b.qiang_count) return a.qiang_count>b.qiang_count;else return a.id<b.id;
}int main()
{int n;cin>>n;for(int i=1;i<=n;i++) a[i].id=i;for(int i=1;i<=n;i++){int k;cin>>k;for(int j=1;j<=k;j++){int id,w;cin>>id>>w;a[id].qiang_w+=w;a[id].qiang_count++;a[i].fa_w+=w;}}for(int i=1;i<=n;i++) a[i].res=a[i].qiang_w-a[i].fa_w;sort(a+1,a+n+1,cmp);for(int i=1;i<=n;i++) printf("%d %.2f\n",a[i].id,a[i].res*1.0/100);return 0;
}

L2-010 排座位

思路:

#include <bits/stdc++.h>
using namespace std;
const int N=110;
int g[N][N];
int n,m,k;bool check(int a,int b)
{for(int i=1;i<=n;i++)if(g[a][i]==1&&g[b][i])return true;return false;
}
int main()
{cin>>n>>m>>k;while(m--){int a,b,r;cin>>a>>b>>r;g[a][b]=g[b][a]=r;}while(k--){int a,b;cin>>a>>b;if(g[a][b]==1) puts("No problem");else if(g[a][b]==0) puts("OK");else if(g[a][b]==-1&&check(a,b)) puts("OK but...");else puts("No way");}return 0;
}

L2-011 玩转二叉树 - 前中序遍历构建树+层序遍历

思路: 和L2-006 树的遍历一模一样

  • 先通过中序遍历和前序遍历确定出树  因为题目要求左右子树对调 所以递归构建的时候反一下就可以了
  • 然后用队列进行层序遍历 根节点入队 然后根节点的左右结点入队 每次取队头输出然后扔掉

#include <bits/stdc++.h>
using namespace std;const int N=55;
int mid[N],pre[N];typedef struct node
{int data;node *l,*r;
}node,*tree;tree create(int len,int *mid,int *pre)
{if(!len) return NULL;tree T=NULL;T=(tree)malloc(sizeof(struct node));T->l=T->r=NULL;T->data=pre[0]; //前序遍历的第一个是根节点int i=0;for(i=0;i<len;i++) //让i指针定位到中序遍历的根节点位置 !这里注意不能int i=0 要不然记录不了i值if(mid[i]==T->data) break;//因为要镜面翻转:左右子树互换T->r=create(i,mid,pre+1);T->l=create(len-(i+1),mid+i+1,pre+i+1);return T;
}void bfs(tree T)
{queue<tree>q;q.push(T);bool f=false;while(!q.empty()){auto t=q.front();q.pop();if(f) cout<<' ';f=true;if(t->l) q.push(t->l);if(t->r) q.push(t->r);cout<<t->data;}
}int main()
{int n;cin>>n;for(int i=0;i<n;i++) cin>>mid[i];for(int i=0;i<n;i++) cin>>pre[i];tree T=create(n,mid,pre);bfs(T);return 0;
}

✓L2-012 关于堆的判断 - 优先队列+哈希表

大顶堆:每个结点的值都大于等于其左右孩子结点的值;

小顶堆:每个结点的值都小于等于其左右孩子结点的值。

 思路:

  • 用优先队列PriorityQueue来实现小顶堆
  • 把小顶堆转化为数组 并更改数组下标从1开始 这样idx/2就是父节点
  • 用map存 < 结点值,下标 >
  • 逐步实现四个查询步骤即可 详见代码
import java.util.*;public class Main{public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=sc.nextInt(),m=sc.nextInt();Queue<Integer>q=new PriorityQueue<>();Map<Integer,Integer> mp=new HashMap<>();String s;for(int i=0;i<n;i++) q.offer(sc.nextInt());//把优先队列(小顶堆)转化到数组Integer[] t=q.toArray(new Integer[n]);int[] a=new int[n+1]; //因为索引从1开始 所以是n+1int cnt=1;//修改数组索引从1开始 这样idx/2就是父结点for(int i=0,j=1;i<n;i++)a[j++]=t[i].intValue();for(int i=1;i<=n;i++) {mp.put(a[i],cnt);cnt++;}sc.nextLine(); //接收回车while(m-->0){boolean f=false;s=sc.nextLine();String[] str=s.split(" ");if(s.indexOf("root")!=-1){int root=Integer.parseInt(str[0]);if(mp.get(root)==1) f=true;}else if(s.indexOf("siblings")!=-1){int l=Integer.parseInt(str[0]);int r=Integer.parseInt(str[2]);l=mp.get(l);r=mp.get(r);if(l/2==r/2) f=true;}else if(s.indexOf("parent")!=-1){int parent=Integer.parseInt(str[0]);int child=Integer.parseInt(str[5]);if(mp.get(child)/2==mp.get(parent)) f=true;}else{int child=Integer.parseInt(str[0]);int parent=Integer.parseInt(str[5]);if(mp.get(child)/2==mp.get(parent)) f=true;}if(f) System.out.println("T");else System.out.println("F");}}
}

【天梯赛 - L2习题集】啃题(12 / 44)相关推荐

  1. 团体程序设计天梯赛-L2组

    团体程序设计天梯赛-L2组 -------------------------------------------------------------------------------- 题目传送门 ...

  2. 【L2-040 哲哲打游戏】天梯赛L2题集

    天梯赛L2-40 题目详情: 思路: 先来一张我自己的手写解析图: (字比较丑,不过呢没有对样例推到完整,这种东西最好自己推一遍哈) 我感觉想清楚这三个问题就很有思路啦: 1.开始地址是什么? 2.如 ...

  3. PTA 程序设计天梯赛(41~60题)

    文章目录 41.整除光棍 (20 分) 42. 装睡 (10 分) 43.矩阵A乘以B (15 分) 44. 倒数第N个字符串 (15 分) 45.打折 (5 分) 46. 2018我们要赢 (5 分 ...

  4. 团体程序设计天梯赛 L2 题目合集

    前言 发现自己还能再参加一次天梯赛,在高兴之余,决定把在赛前将所有的天梯赛真题过一遍,希望自己可以取得理想的成绩.目前 L1 的题目已经刷完,打算在赛前刷完 L2 的题目. 本来想 L2 的题目都写个 ...

  5. 【L2-020 功夫传人】天梯赛L2系列详解

    天梯赛L2-020 功夫传人 题目详情: 思路: 这个题目的看着就感觉需要深搜一下,不妨将样例画出来,思路就突然涌来了.很明显的一道深搜的题目: 题目刚开始输入的一行信息整体的信息:宗门人数,祖师爷功 ...

  6. 【L2-022 重排链表】天梯赛L2系列详细解答

    天梯赛L2-022 重排链表 题目详情: 输入样例: 00100 6 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 6823 ...

  7. 2021天梯赛L2题解全集

    L2-037 包装机 (25 分) 其实就是个模拟,按照题目意思写下去吧,也不知道为什么比赛的时候一直只能拿20分(用char数组+ int变量模拟栈) 赛后直接用栈写的一发满分就很奇怪...主要是题 ...

  8. 【L2-034 口罩发放】天梯赛L2详解

    天梯赛L2-034 口罩发放 题目详情: 思路: 输入要求很长,猛然一看非常没有思路.但是写题的感觉还是有的.怎么写呢?我是从筛选信息一步一步入手的. 1.首先:这么长的信息,以我的水平,最好用结构体 ...

  9. 【L2-019 悄悄关注 】天梯赛L2系列详解

    天梯赛L2-019 悄悄关注 题目详情: 输入样例1: 10 GAO3 Magi Zha1 Sen1 Quan FaMK LSum Eins FatM LLao 8 Magi 50 Pota 30 L ...

最新文章

  1. 数据结构和算法:(3)3.2线性表的链式存储结构
  2. angular4 下载文件 Excel zip包
  3. 【linux草鞋应用编程系列】_4_ 应用程序多线程
  4. 解决oracle主键问题,解决renren-security使用oracle主键问题
  5. python类型转换astype-numpy数据类型dtype转换
  6. 量子计算: 1秒完成传统计算机100年的任务量
  7. 华为交换机vlan配置
  8. Learn Python the Hard Way: 字典
  9. 为什么个体户贷款那么难
  10. 梯度下降、牛顿法、拟牛顿法详细介绍
  11. “三峡水怪”的真面目竟是这个!水怪:我不要面子的吗?
  12. 年轻人“颜值消费”崛起 分期乐联手屈臣氏发力95后美妆护理市场
  13. 机房收费系统-数据库设计说明书
  14. vgp虚拟路面_某车型开发阶段实际道路谱和虚拟路面谱对比分析.pdf
  15. Google Daydream实验室:VR设计的三大要素
  16. 扑克牌排序(结构体)
  17. 心愿作文计算机,关于心愿的作文150字
  18. 艾永亮:亏损7年到年销100亿,百果园如何在小水果里做出大生意?
  19. 浏览器暗黑模式-Dark深色模式
  20. 优麒麟20.10 wifi 开关打不开解决方案

热门文章

  1. pet-shop Dapp开发(下)
  2. 达梦DM装完数据库,bin下面没有disql文件是怎么回事?
  3. CESM简单应用:将HadiSST作为海温强迫场进行CESM控制实验 -compset F FC5 FCN
  4. Android 获取夜深模拟器中的文件获取不到
  5. 拉面哥的火爆看新媒体时代的底层逻辑!
  6. IMP811REUS/T小秘密
  7. c语言oj猜灯谜,元宵节灯谜——文学典籍类
  8. Ubuntu 16.04卸载LibreOffice等不常用软件
  9. oracle的package是什么意思,Oracle的Package的作用及用法
  10. Java中的包(package)详情解释