天梯训练L3
肿瘤诊断
题目大意就是给一个三维的01图,求这张01图中构成大于等于T的连通块的1的总数。
bfs 搜索
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 1e5+10; 4 inline int read(){ 5 int c=0, f=1; char ch = getchar(); 6 while (ch<'0'||ch>'9'){ if(ch=='-') f = -1; ch = getchar(); } 7 while (ch>='0'&&ch<='9'){ c = c*10+ch-'0'; ch = getchar();} 8 return c*f; 9 } 10 int n, m, l, t, ans = 1; 11 bool mp[70][1300][130]; 12 int dx[] = {1, -1, 0, 0, 0, 0}; 13 int dy[] = {0, 0, 1, -1, 0, 0}; 14 int dz[] = {0, 0, 0, 0, 1, -1}; 15 struct node 16 { 17 int x, y, z; 18 }; 19 20 int bfs(int x,int y,int z){ 21 mp[x][y][z] = 0; 22 queue<node> q; 23 int res = 0; 24 q.push((node){x, y, z}); 25 while (!q.empty()) 26 { 27 node fa = q.front(); 28 q.pop(); 29 ++res; 30 for(int i = 0;i < 6;i ++){ 31 int nx = fa.x + dx[i]; 32 int ny = fa.y + dy[i]; 33 int nz = fa.z + dz[i]; 34 if(!nx|| nx>l|| !ny|| ny>m|| !nz|| nz>n) continue; 35 if(mp[nx][ny][nz]){ 36 mp[nx][ny][nz] = 0; 37 q.push((node){nx, ny, nz}); 38 } 39 } 40 } 41 return res; 42 } 43 44 int main() 45 { 46 m = read(); n = read(); l = read(); t = read(); 47 for(int i=1;i<=l;i++){ 48 for(int j=1;j<=m;j++){ 49 for(int k=1;k<=n;k++){ 50 mp[i][j][k] = read(); 51 } 52 } 53 } 54 int sum = 0; 55 for(int i=1;i<=l;i++){ 56 for(int j=1;j<=m;j++){ 57 for(int k=1;k<=n;k++){ 58 if(mp[i][j][k]){ 59 ans = bfs(i,j,k); 60 if(ans>=t) sum += ans; 61 } 62 } 63 } 64 } 65 cout<<sum; 66 return 0; 67 }
特殊堆栈
题目大意就是实现三种操作,分别为出栈,入栈,取中值。
思路1:
因为堆栈是无序的,在堆栈中查找中值非常的麻烦,所以考虑开多一个数组进行排序,排序后中值就是n+1/2的位置;
因为是依次给出的操作,所以选择使用二分插入排序维护有序数组;
而普通的数组进行插入排序难以实现,所以选择动态数组vector;
使用一个数组用作堆栈进行出栈入栈操作,一个动态数组为堆栈元素的有序数组进行取中值操作;
vector的基本操作:https://blog.csdn.net/wkq0825/article/details/82255984
#include<algorithm> 中二分查找函数的使用:https://blog.csdn.net/jadeyansir/article/details/77015626
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int t,tmp; 5 string op; 6 vector<int> stk,a; 7 8 int main() 9 { 10 cin>>t; 11 while(t--){ 12 cin>>op; 13 if(op == "Push"){ 14 //入栈 15 cin>>tmp; 16 stk.push_back(tmp); 17 a.insert(upper_bound(a.begin(),a.end(),tmp),tmp); 18 } 19 else if(op == "Pop"){ 20 //出栈 21 if(!stk.size()) cout<<"Invalid\n"; 22 else{ 23 tmp = stk[stk.size()-1]; 24 cout<<tmp<<endl; 25 26 stk.pop_back(); 27 a.erase(lower_bound(a.begin(),a.end(),tmp)); 28 } 29 30 } 31 else if(op == "PeekMedian"){ 32 //取中值 33 tmp = a.size(); 34 if(!tmp) cout<<"Invalid\n"; 35 else{ 36 if(tmp&1){ 37 cout<<a[tmp/2]<<endl; 38 } 39 else 40 cout<<a[tmp/2-1]<<endl; 41 } 42 } 43 } 44 return 0; 45 }
思路2:

取中值操作也就是找一个第k小的数,k=n+1/2;
对于第k小的数,说明k的左边有n+1/2-1个数,右边有n+1/2+1个数。
那就可以二分查找一个值t,若这个t符合左边有第k小数性质的话,说明就是答案。
那么如何快速的知道数值t的左右两个区间【1,t】【t,1e5】的元素个数呢,可以用线段树或树状数组维护区间【1,1e5】中每个整数在序
列中出现的次数,从而快速的更新和查找区间【l,r】的元素个数。
#include<bits/stdc++.h> #define MAXN 100010 #define inf 100000 #define lson rt<<1 #define rson rt<<1|1 using namespace std; int sum[MAXN*4]; int n,tot=0,stk[MAXN],mx,t,tmp; string op; void add(int l,int r,int rt,int k,int val){ if(l==k && r==k){ sum[rt] += val; return ; } int mid = (l+r)>>1; if(mid>=k) add(l,mid,lson,k,val); else add(mid+1,r,rson,k,val); sum[rt] = sum[lson]+sum[rson]; return ; } int fid(int l,int r,int rt,int ul,int ur){ if(ul<=l && r<=ur){ return sum[rt]; } int ans = 0; int mid = (l+r)>>1; if(ul<=mid) ans += fid(l,mid,lson,ul,ur); if(ur>mid) ans += fid(mid+1,r,rson,ul,ur); return ans; } int getmid(int x){ int l = 1, r = mx; while(l<r){ int mid = (l+r)>>1; int num = fid(1,inf,1,1,mid); if(num>=x) r = mid; else l = mid+1; } return l; } int main() { cin>>t; while(t--){ cin>>op; if(op == "Push"){ //入栈 cin>>tmp; stk[++tot] = tmp; mx = max(tmp,mx); add(1,inf,1,tmp,1); } else if(op == "Pop"){ //出栈 if(!tot) cout<<"Invalid\n"; else{ add(1,inf,1,stk[tot--],-1); cout<<stk[tot+1]<<endl; } } else if(op == "PeekMedian"){ //取中值 if(!tot) cout<<"Invalid\n"; else{ tmp = (tot+1)>>1; cout<<getmid(tmp)<<endl; } } } return 0; }
天梯地图
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792
题目大意:在图中找两条路径,一条路径使得起点到终点的距离最短,如果有距离一样短的其他路径则输出结点数最少的路径,另一条路径是
使得起点到终点的时间最短,如果有时间一样短的路径则输出距离最短的路径;
以距离为权值求一次单源最短路;
以时间为权值求一次单源最短路;
最后判断一下路径是否相同即可;
#include <bits/stdc++.h> using namespace std; const int N=505,INF=0x3f3f3f3f; int n,m; struct edg{ int to,w,l; }E1,E2; vector<edg>G[N],T[N]; int dis[N],pre[N],vis[N],in[N],num[N],out[N]; int diss[N],sum[N]; struct Node{ int to,w; bool operator <(const Node&x)const{ return x.w<w; } }p,q; void printff(vector<int> vec){ int flag=0; for(int i=vec.size()-1;i>=0;i--){ if(flag) cout << " => "; cout << vec[i],flag=1; } cout << endl; } int judge(vector<int>vec,vector<int>vec1){ if(vec.size()!=vec1.size()) return 0; for(int i=0;i<vec.size();i++) if(vec[i]!=vec1[i]) return 0; return 1; } void dij1(int start){ priority_queue<Node> que; for(int i=0;i<=N-1;i++) dis[i]=INF,pre[i]=-1,vis[i]=0; que.push({start,0}),dis[start]=0,num[start]=1; while(!que.empty()){ p=que.top(),que.pop(); int u=p.to,v,w,z; if(vis[u]) continue; vis[u]=1; for(auto X:G[u]){ v=X.to,w=X.w,z=1; if(dis[v]>w+p.w) dis[v]=w+p.w,pre[v]=u,num[v]=num[u]+1,q.to=v,q.w=dis[v],que.push(q); else if(dis[v]==w+p.w){ if(num[v]>num[u]+1) num[v]=num[u]+1,pre[v]=u; } } } } void dij2(int start) { priority_queue<Node> que; for(int i=0;i<=N-1;i++) pre[i]=-1,vis[i]=0,sum[i]=INF,diss[i]=0; que.push({start,0}),diss[start]=0,sum[start]=0; while(!que.empty()){ p=que.top(),que.pop(); int u=p.to,v,w,z; if(vis[u]) continue; vis[u]=1; for(auto X:G[u]){ v=X.to,w=X.w,z=X.l; if(sum[v]>z+p.w) sum[v]=z+p.w,pre[v]=u,diss[v]=diss[u]+w,q.to=v,q.w=sum[v],que.push(q); else if(sum[v]==z+p.w){ if(diss[v]>diss[u]+w) diss[v]=diss[u]+w,pre[v]=u; } } } } int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=0,d1,d2,d3,d4,d5;i<m;i++){ cin>>d1>>d2>>d3>>d4>>d5; G[d1].push_back({d2,d4,d5}); if(!d3){ G[d2].push_back({d1,d4,d5}); } } vector<int> vec,vec1; int start,ending; cin>>start>>ending; dij2(start); int pos=ending; while(pos!=-1) vec.push_back(pos),pos=pre[pos]; dij1(start); pos=ending; while(pos!=-1) vec1.push_back(pos),pos=pre[pos]; if(judge(vec,vec1)) cout<<"Time = "<<sum[ending]<<"; "<<"Distance = "<<dis[ending]<<": ",printff(vec); else{ cout << "Time = " << sum[ending] <<": "; printff(vec); cout << "Distance = " << dis[ending] <<": "; printff(vec1); } return 0; }

浙公网安备 33010602011771号