目录
思路:
- #include
- #include
- #include
- 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
- {
- int t=-1;
- for(int j=0;j
- if(!st[j]&&(t==-1||dist[j]
- t=j;
- st[t]=true;
-
- for(int j=0;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[j]=sumw[t]+w[j];
- pre[j]=t;
- }
- }
- }
- }
- cout<
' '< - //把经过的点倒序输出
- cout<
- for(int i=d;i!=s;i=pre[i])
- prt[cnt++]=i;
- reverse(prt,prt+cnt);
- for(int i=0;i
- cout<<' '<
- }
-
-
- int main()
- {
- cin>>n>>m>>s>>d;
- for(int i=0;i
>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
- #include
- #include
- #include
- #include
- #include
- 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
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
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
- #include
- #include
- #include
- #include
- #include
- 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
>a[i].w; - for(int i=0;i
>a[i].p; - sort(a,a+n);
- for(int i=0;i
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
- #include
- 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<
data; - }
-
- int main()
- {
- cin>>n;
- for(int i=0;i
>a[i]; - //创建二叉搜索树
- tree T1=nullptr;
- for(int i=0;i
create1(T1,a[i]); - //创建镜像二叉搜索树
- tree T2=nullptr;
- for(int i=0;i
create2(T2,a[i]); - //分非镜像和镜像进行前序遍历 和原序列进行比较
- pre1(T1),pre2(T2);
- bool f1=false,f2=false;
- for(int i=0;i
if(p1[i]!=a[i]) f1=true; - for(int i=0;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
- #include
- 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
- #include
- #include
- 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
- 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
q; - q.push(T);
- while(q.size())
- {
- auto t=q.front();
- q.pop();
-
- if(flag) cout<<' ';
- flag=true;
-
- cout<
data; - if(t->l)q.push(t->l);
- if(t->r)q.push(t->r);
- }
- }
-
- int main()
- {
- cin>>n;
- for(int i=0;i
>po[i]; - for(int i=0;i
>mid[i]; - tree T=reback(n,po,mid);
- bfs(T);
- return 0;
- }

!L2-007 家庭房产 - 并查集+结构体+排
- #include
- 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
- }
-
- int main()
- {
- for(int i=0;i
- cin>>n;
- for(int i=0;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
- {
- 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
if(fam[i].num) sum++; - cout<
- sort(fam,fam+N,cmp);
- for(int i=0;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
- 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
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<
- return 0;
- }
- #include
- 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
size();l++) - {
- bool f=false;
- int i=l,j=l+len-1;
- while(i
- {
- if(s[i]!=s[j])
- {
- f=true;
- break;
- }
- i++,j--;
- }
- if(!f)
- {
- cout<
- return 0;
- }
- }
- }
L2-009 抢红包 - 模拟+排序
思路:
- #include
- 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
- }
-
- 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
- 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
- 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
//让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
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<
data; - }
- }
-
- int main()
- {
- int n;
- cin>>n;
- for(int i=0;i
>mid[i]; - for(int i=0;i
>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
q=new PriorityQueue<>(); - Map
mp=new HashMap<>(); - String s;
- for(int i=0;i
- q.offer(sc.nextInt());
-
- //把优先队列(小顶堆)转化到数组
- Integer[] t=q.toArray(new Integer[n]);
- int[] a=new int[n+1]; //因为索引从1开始 所以是n+1
- int cnt=1;
- //修改数组索引从1开始 这样idx/2就是父结点
- for(int i=0,j=1;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");
- }
-
- }
- }
-
相关阅读:
【opencv】多版本安装
华钜同创:亚马逊开店有哪些注意事项
(附源码)springboot在线考试系统 毕业设计 160935
milvus集合管理
两天学会微服务网关Gateway-Gateway路由规则
JSP+MySQL基于ssm的主题酒店管理系统
特斯拉第三方应用开发指南(一)
【Spring】Spring MVC 拦截器的使用
一篇文章带你学懂Redis
知识图谱从入门到应用——知识图谱推理:基础知识
-
原文地址:https://blog.csdn.net/weixin_61639349/article/details/126463011