【CCCC】PAT : 团体程序设计天梯赛-练习集 L3 答案

顶着满课,整整一星期,终于咕完了。(;´д`)ゞ

知识点分类(23):

1、搜索模拟(5):BFS,DFS,最短路,路径打印

2、计算几何(5):找规律,斜率计算,极角排序,三角形面积,三点共线,凸包

3、数据结构(5):栈,并查集,二叉树,堆,线段树

4、图论模板(4):Dijkstra,Floyd

4、零零碎碎(4):数学(1)+物理(1)+DP(2)

标号 代码提交 分数 通过率 算法标签 题解链接
L3-001 凑零钱 30 0.29 01背包+路径打印 AC
L3-002 特殊堆栈 30 0.35 栈+二分 AC
L3-003 社交集群 30 0.44 并查集 AC
L3-004 肿瘤诊断 30 0.30 三维BFS AC
L3-005 垃圾箱分布 30 0.31 Dijkstra AC
L3-006 迎风一刀斩 30 0.23 计算几何+找规律 AC
L3-007 天梯地图 30 0.30 Dijkstra+路径打印 AC
L3-008 喊山 30 0.48 BFS最长路 AC
L3-009 长城 30 0.30 计算几何+凸包 AC
L3-010 是否完全二叉搜索树 30 0.41 完全二叉树+层次遍历 AC
L3-011 直捣黄龙 30 0.25 Dijkstra+点权+路径条数 AC
L3-012 水果忍者 30 0.27 斜率计算+贪心+枚举 AC
L3-013 非常弹的球 30 0.51 高中物理 AC
L3-014 周游世界 30 0.39 DFS最短路+路径打印 AC
L3-015 球队“食物链” 30 0.26 全排列搜索 AC
L3-016 二叉搜索树的结构 30 0.26 手写堆+判断节点 AC
L3-017 森森快递 30 0.29 线段树+贪心排序 AC
L3-018 森森美图 30 0.51 计算几何+BFS最短路 AC
L3-019 代码排版 30 0.25 大模拟 AC
L3-020 至多删三个字符 30 0.27 序列DP AC
L3-021 神坛 30 0.34 计算几何+极角排序 AC
L3-022 地铁一日游 30 0.42 Floyd+大模拟 AC
L3-023 计算图 30 0.46 高等数学 AC

Codes

L3-001

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;//RE3,4
const int maxm = 110;
int v[maxn], dp[maxm], pre[maxn][maxm];
bool cmp(int a, int b){return a>b;}
int main(){int n, m;cin>>n>>m;for(int i = 1; i <= n; i++)cin>>v[i];sort(v+1,v+n+1,cmp);//结论:降序排序=最小字典序for(int i = 1; i <= n; i++){for(int j = m; j >= v[i]; j--){if(dp[j]<=dp[j-v[i]]+v[i]){dp[j]=dp[j-v[i]]+v[i]; //选择的代价为v[i],价值为v[i]pre[i][j] = 1;//选择了硬币i,标记当前背包位置,记录路径}}}if(dp[m]!=m){//容量为m(面额)的背包能获得的最大价值为m。。cout<<"No Solution"<<endl;return 0;}//路径打印int ok = 0;for(int i=n, j=m; i>=1 && j>=0; i--){//注意顺序必须是逆序,和前面相反if(pre[i][j]){if(!ok){cout<<v[i];ok=1;}else cout<<" "<<v[i];j -= v[i];//当第i个硬币选中,剩余价值-=vi[i];}}return 0;
}

L3-002

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
stack<int>stk;
//multiset<int>se;
vector<int>order;
int main(){//freopen("ans.cpp","r",stdin);int T;  cin>>T;while(T--){string s;  cin>>s;int re = 0;if(s=="Push"){int x;  cin>>x;stk.push(x);order.insert(lower_bound(order.begin(), order.end(), stk.top()), stk.top());}if(s=="Pop"){if(stk.size()){cout<<stk.top()<<"\n";order.erase(lower_bound(order.begin(), order.end(), stk.top()));stk.pop();}else{re = 1;}}if(s=="PeekMedian"){if(stk.size()){//cout<<stk.size()<<" ";cout<<order[(stk.size()-1)/2]<<endl;}else{re = 1;}}if(re)cout<<"Invalid\n";}return 0;
}

L3-003

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;vector<int>man[maxn];
bool cmp(pair<int,int> a, pair<int,int> b){return a.second>b.second;}int fa[maxn+10];
void init(int n){for(int i = 0; i <= n; i++)fa[i]=i;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void merge(int x, int y){x=find(x);y=find(y);if(x!=y)fa[x]=y;}int main(){int n;  cin>>n;init(maxn);for(int i = 1; i <= n; i++){int k;  scanf("%d:",&k);int x;  cin>>x;man[i].push_back(x);for(int j = 2; j <= k; j++){int xx;  cin>>xx;merge(x,xx);man[i].push_back(xx);}}map<int,int>ma;for(int i = 1; i <= n; i++){ma[find(man[i][0])]++;}vector<pair<int,int> >vec(ma.begin(),ma.end());sort(vec.begin(),vec.end(),cmp);cout<<vec.size()<<endl;for(int i = 0; i < vec.size()-1; i++)cout<<vec[i].second<<" ";cout<<vec[vec.size()-1].second;/*map<int,int>::reverse_iterator it = ma.rbegin();cout<<(it->second);  it++;for( ; it != ma.rend(); it++)cout<<" "<<(it->second);*/return 0;
}

L3-004

#include<bits/stdc++.h>
using namespace std;int n, m, l, t, a[61][129][1287];int ans = 0;
struct xyz{int x, y, z;};
int dx[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
int check(int x, int y, int z){if(x<0||y<0||z<0||x>=l||y>=n||z>=m)return 0;return 1;}
void bfs(int x, int y, int z){queue<xyz>q;  q.push(xyz{x,y,z}); a[x][y][z] = 0;int sum = 1;while(q.size()){xyz k = q.front(); q.pop();for(int i = 0; i < 6; i++){xyz kk = k;//kk!=k,WA3,6,这TM也能过样例?!kk.x += dx[i][0];kk.y += dx[i][1];kk.z += dx[i][2];if(check(kk.x,kk.y,kk.z) && a[kk.x][kk.y][kk.z]){a[kk.x][kk.y][kk.z] = 0;sum++;q.push(kk);}}}if(sum>=t)ans += sum;
}int main(){cin>>n>>m>>l>>t;for(int k = 0; k < l; k++)for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)cin>>a[k][i][j];for(int k = 0; k < l; k++)for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)if(a[k][i][j])bfs(k,i,j);cout<<ans<<endl;return 0;
}

L3-005

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1050;//RE6?int n, m, k, ds;
struct lajitong{string id;double minds, aveds;bool operator < (const lajitong &b){if(minds != b.minds)return minds>b.minds;if(aveds != b.aveds)return aveds<b.aveds;return id < b.id;}
};int e[maxn][maxn], dist[maxn], vis[maxn];
void Dijkstra(int u){memset(dist,0x3f,sizeof(dist));memset(vis,0,sizeof(vis));dist[u] = 0;for(int i = 1; i <= n+m; i++){int v = -1, _min = (1e9);for(int j = 1; j <= n+m; j++)if(!vis[j] && dist[j]<_min){_min = dist[j]; v= j;}if(v==-1)return ;vis[v] = 1;for(int j = 1; j <= n+m; j++){if(!vis[j] && dist[j]>dist[v]+e[v][j]){//vis[jjjjjj],NotVVVVVdist[j] = dist[v]+e[v][j];}}}
}int main(){//inputcin>>n>>m>>k>>ds;memset(e,0x3f,sizeof(e));for(int i = 0; i < k; i++){char a[10], b[10]; int c;scanf("%s%s%d",a,b,&c);int aa = (a[0]=='G' ? n+atoi(&a[1]) : atoi(a));int bb = (b[0]=='G' ? n+atoi(&b[1]) : atoi(b));e[aa][bb] = e[bb][aa] = c;}//对于每个垃圾桶,跑完dij后统计最短距离和平均距离lajitong ans;for(int i = 1; i <= m; i++){Dijkstra(n+i);double aveds = 0, minds = dist[1];int flag = 1;for(int j = 1; j <= n; j++){aveds += dist[j];minds = min(minds, dist[j]*1.0);if(dist[j]>ds)flag = 0; //dist[jjjjjj],NotIIIIII}//更新答案lajitong tmp = lajitong{"G"+to_string(i),minds,aveds/n};//cout<<flag<<"\n";if(flag && (ans.id.empty() || tmp<ans)){ans = tmp;}}if(ans.id.empty())cout<<"No Solution"<<endl;elseprintf("%s\n%.1lf %.1lf", ans.id.c_str(), ans.minds, ans.aveds);return 0;
}

L3-006

//超级注释版
#include<bits/stdc++.h>
using namespace std;//1.分别存储两个图形的斜边(2个点),顶点数,
vector<int> v[2], n;
//2.特判情况:四边形直角腰,矩形个数
vector<int>len; int flag;//1.找到斜边
void deal(int id, vector<int>& x, vector<int>& y){int sz = x.size(); set<int>st;for(int i = 0; i < sz; i++){//相邻点横纵坐标都不等:这两点构成斜边。if(x[i]!=x[(i+1)%sz] && y[i]!=y[(i+1)%sz]){st.insert(i);  st.insert((i+1)%sz);//如果是四边形:存储直角腰的长度 if(sz==4)len.push_back(abs(x[(i+2)%4]-x[(i+3)%4])+abs(y[(i+2)%4]-y[(i+3)%4]));}}if(st.size()==0){//没有斜边,所以是矩形//存下两条直角边v[id].push_back(abs(x[2]-x[0]));v[id].push_back(abs(y[2]-y[0]));flag++; //矩形个数+1}else{//存储斜边(2个端点)for(int i : st){v[id].push_back(x[i]);v[id].push_back(y[i]);}}
}
//2.情况判断
void solve(){//最多也就三边形+五边形,超过8个点就错。if(n[0]<=5 && n[1]<=5 && n[0]+n[1]<=8){if(flag==2){//两个矩形//只要矩形A(x,y)两条直接边有一条能和矩形B合上就行int x=v[0][0],y=v[0][1],c=v[1][0],d=v[1][1];if(x==c||x==d||y==c||y==d){cout<<"YES\n";return;}}if(flag==0){//没有矩形//如果没有斜边,不成立if(v[0].size()==4 && v[1].size()==4){//特判直角腰if(n[0]==4&&n[1]==4&&len[0]!=len[1]){cout<<"NO\n";return;}//存下两条直角边(斜边分别做垂直的直角三角形)int x=abs(v[0][2]-v[0][0]),y=abs(v[0][3]-v[0][1]); if(x>y) swap(x,y);int c=abs(v[1][2]-v[1][0]),d=abs(v[1][3]-v[1][1]); if(c>d) swap(c,d);//当且仅当直角边都相等,斜边相等if(x==c&&y==d){cout<<"YES\n";return;}}}//一个矩形的情况不存在}cout<<"NO\n";
}int main(){int T;  cin>>T;while(T--){//1. 变量全部初始化flag = 0; n.clear();  len.clear();v[0].clear();  v[1].clear();//2. 输入两个多边形for(int i = 0; i < 2; i++){int k;  cin>>k;  n.push_back(k);vector<int>x(k), y(k);for(int j = 0; j < k; j++)cin>>x[j]>>y[j];//2.1 找到斜边deal(i,x,y);}//3. 结论判断solve();}return 0;
}

L3-007

//AC
#include<bits/stdc++.h>
using namespace std;
const int maxn = 550;int n, m, s, t;
int e[2][maxn][maxn], dist[2][maxn], vis[2][maxn], pre[2][maxn], w[2][maxn];
void Dijkstra(int rk){memset(dist[rk],0x3f,sizeof(dist[rk]));memset(vis[rk],0,sizeof(vis[rk]));memset(pre[rk],-1,sizeof(pre[rk]));dist[rk][s] = 0;for(int i = 0; i < n; i++){int u = -1, _min = 1e9;for(int j = 0; j < n; j++){if(!vis[rk][j] && dist[rk][j]<_min){_min = dist[rk][j];  u = j;}}if(u==-1)return ;vis[rk][u] = 1;for(int j = 0; j < n; j++){if(!vis[rk][j] && dist[rk][j]>dist[rk][u]+e[rk][u][j]){dist[rk][j] = dist[rk][u]+e[rk][u][j];pre[rk][j] = u;//距离if(rk==0){w[rk][j] = w[rk][u]+1;//+1?!!:WA4!!                   }//时间if(rk==1){w[rk][j] = w[rk][u]+e[!rk][u][j];//WA2!}}else if(!vis[rk][j] && dist[rk][j] == dist[rk][u]+e[rk][u][j]){//距离if(rk==0){if(w[rk][j] > w[rk][u]+1){w[rk][j] = w[rk][u]+1;pre[rk][j] = u;}}//时间if(rk==1){if(w[rk][j] > w[rk][u]+e[!rk][u][j]){w[rk][j] = w[rk][u]+e[!rk][u][j];pre[rk][j] = u;}}                }}}
}
void Print(int rk, int x){if(x==-1){return ;}else{Print(rk, pre[rk][x]);printf(" %d =>", x);}
}int main(){memset(e,0x3f,sizeof(e));cin>>n>>m;for(int i = 1; i <= m; i++){int a, b, on, le, ti;cin>>a>>b>>on>>le>>ti;if(on==1){e[0][a][b] = le;e[1][a][b] = ti;}else{e[0][a][b] = le;e[1][a][b] = ti;e[0][b][a] = le;e[1][b][a] = ti;}}cin>>s>>t;Dijkstra(0);Dijkstra(1);int ok = 1, i = pre[0][t], j = pre[1][t];while(i!=-1 && j!=-1){if(pre[0][i] != pre[0][j]){ok=0;break;}i = pre[0][i];j = pre[1][j];}if(ok){printf("Time = %d;",dist[1][t]);printf(" Distance = %d:",dist[0][t]);Print(1,pre[1][t]);printf(" %d\n",t);return 0;}printf("Time = %d:",dist[1][t]);Print(1,pre[1][t]);printf(" %d\n",t);printf("Distance = %d:",dist[0][t]);Print(0,pre[0][t]);printf(" %d",t);return 0;
}

L3-008

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
vector<int>G[maxn];
int vis[maxn];
bool cmp(int a, int b){return a>b;}
int bfs(int x){memset(vis,0,sizeof(vis));int u = -1, val = 1e9;queue<pair<int,int> >q;q.push({x,1});vis[x] = 1;while(q.size()){pair<int,int> t = q.front();  q.pop();vis[t.first] = 1;for(int i = 0; i < G[t.first].size(); i++){sort(G[t.first].begin(),G[t.first].end(),cmp);//编号小的先输出if(!vis[G[t.first][i]])q.push({G[t.first][i],t.second+1});}if(u==-1 || t.second>val){val = t.second;u = t.first;}else if(t.second==val && t.first<u){u = t.first;}}  return u;
}
int main(){int n, m, k;cin>>n>>m>>k;for(int i = 1; i <= m; i++){int a, b;  cin>>a>>b;G[a].push_back(b);G[b].push_back(a);}for(int i = 1; i <= k; i++){int x;  cin>>x;if(G[x].size()==0)cout<<0<<endl;else cout<<bfs(x)<<endl;}return 0;
}

L3-009

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e5+10;LL x[maxn], y[maxn];
int stk[maxn], top;
set<int>se;bool check(int a, int b, int c){//向量ab在ac下面(kab<kac),b是凹点return (x[c]-x[a])*(y[b]-y[a])<=(x[b]-x[a])*(y[c]-y[a]);
}int main(){ios::sync_with_stdio(false);int n;  cin>>n;for(int i = 0; i < n; i++){cin>>x[i]>>y[i];if(top>=1){while(top>=2 && check(i,stk[top-1],stk[top-2]))top--;//b是凹点不要它了if(stk[top-1])se.insert(stk[top-1]);//找到凸点了入栈}stk[top++] = i;}cout<<se.size()<<endl;return 0;
}

L3-010

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;int Tree[maxn];
void update(int root, int val){if(!Tree[root])Tree[root] = val;else if(val > Tree[root])update(root*2, val);else update(root*2+1,val);
}int main(){int n;  cin>>n;for(int i = 1; i <= n; i++){int x;  cin>>x;  update(1,x);}int ok = 0, cnt = 0;for(int i = 1; i < maxn; i++){if(Tree[i]){if(ok)cout<<" ";else ok = 1;cout<<Tree[i];cnt = i;}}if(cnt > n)cout<<"\nNO\n";else cout<<"\nYES\n";return 0;
}

L3-011

#include<bits/stdc++.h>
using namespace std;
const int maxn = 250;map<string,int>ma;
map<int,string>mb;
int tot = 1;
int getid(string s){if(ma.count(s))return ma[s];else{mb[tot] = s;ma[s] = tot;tot++;return ma[s];}
}int n, k, s, t;
int e[maxn][maxn], w[maxn];
int dist[maxn], vis[maxn], pre[maxn], cnt[maxn], weight[maxn], cc[maxn];
void Dijkstra(int u){memset(dist, 0x3f,sizeof(dist));memset(pre,-1,sizeof(pre));dist[u] = 0; cnt[u] = 0; weight[u]=w[u];  cc[u] = 1;for(int i = 1; i <= n; i++){int v = -1, minn = 1e9;for(int j = 1; j <= n; j++){if(!vis[j] && dist[j]<minn){minn = dist[j];v = j;}}vis[v] = 1;for(int j = 1; j <= n; j++){if(!vis[j] && dist[j]>dist[v]+e[v][j]){dist[j] = dist[v]+e[v][j];cc[j] = cc[v];cnt[j] = cnt[v]+1;weight[j] = weight[v]+w[j];pre[j] = v;}else if(!vis[j] && dist[j]==dist[v]+e[v][j]){cc[j] += cc[v];//+=if(cnt[j]<cnt[v]+1){cnt[j] = cnt[v]+1;weight[j] = weight[v]+w[j];pre[j] = v;}else if(cnt[j]==cnt[v]+1){if(weight[j]<weight[v]+w[j]){weight[j] = weight[v]+w[j];pre[j] = v;}}}}}
}int main(){cin>>n>>k;string a,b;  cin>>a>>b;s = getid(a);  t = getid(b);memset(e,0x3f,sizeof(e));for(int i = 1; i < n; i++){string a; int b;  cin>>a>>b;w[getid(a)] = b;}for(int i = 1; i <= k; i++){string a, b;  cin>>a>>b;int aa = getid(a), bb = getid(b);int cc;  cin>>cc;e[aa][bb] = e[bb][aa] = cc;}Dijkstra(s);vector<string>vec;int x = t;while(x!=-1){vec.push_back(mb[x]);x = pre[x];}reverse(vec.begin(),vec.end());for(int i = 0; i < vec.size(); i++){if(i==vec.size()-1)cout<<vec[i]<<endl;else cout<<vec[i]<<"->";}cout<<cc[t]<<" "<<dist[t]<<" "<<weight[t]<<"\n";return 0;
}

L3-012

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
struct seg{ double x, y1, y2; }s[maxn];
bool cmp(seg a, seg b){return a.x<b.x;}
double maxk,mink,ansmaxk,ansmink,ansx,ansy;
int main(){int n;  cin>>n;for(int i = 1; i <= n; i++)cin>>s[i].x>>s[i].y1>>s[i].y2;//y1在上,y2在下sort(s+1,s+n+1,cmp);for(int i = 1; i <= n; i++){ansmaxk = 1e9;ansmink = -1e9;int j;for(j = 1; j <= n; j++){if(j==i)continue;if(i<j){// j在i右侧maxk = (s[i].y2-s[j].y1)/(s[i].x-s[j].x);mink = (s[i].y2-s[j].y2)/(s[i].x-s[j].x);}else{ //j在i左侧maxk = (s[i].y2-s[j].y2)/(s[i].x-s[j].x);mink = (s[i].y2-s[j].y1)/(s[i].x-s[j].x);}if(ansmaxk<mink || ansmink>maxk)break;if(maxk<ansmaxk){ansmaxk = maxk;ansx = s[j].x;ansy = s[j].y1;}ansmink = max(ansmink, mink);}if(j==n+1){//存在解//线段i上取了最低点,则另一条线段要取最高点printf("%.0lf %.0lf %.0lf %.0lf\n",s[i].x,s[i].y2,ansx,ansy); return 0;}}return 0;
}

L3-013

#include<bits/stdc++.h>
using namespace std;
int main(){double w, p; cin>>w>>p;double E = 1000, g = 9.8;double s = 1, sum = 0;while(s>1e-8){//精度s = 2*E/(w/100*g);sum += s;E *= (100-p)/100;}printf("%0.3lf",sum);return 0;
}

L3-014

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;int minCnt, minTrans;
vector<int>path, tempath;int line[maxn][maxn]; //维护两点之间的线路归属
int count(vector<int>a){//给出路径,计算换乘int cnt = -1, preLine = 0;for(int i = 1; i < a.size(); i++){if(line[a[i-1]][a[i]] != preLine)cnt++;preLine = line[a[i-1]][a[i]];}return cnt;
}vector<int>G[maxn]; int vis[maxn];
void dfs(int u, int end, int cnt){if(u==end){if(cnt<minCnt || (cnt==minCnt && count(tempath)<minTrans)){minCnt = cnt;minTrans = count(tempath);path = tempath;}return ;}for(int i = 0; i < G[u].size(); i++){int v = G[u][i];if(!vis[v]){vis[v] = 1;tempath.push_back(v);dfs(v,end,cnt+1);vis[v] = 0;tempath.pop_back();}}
}int main(){int n, m, k, pre, tmp, a, b;cin>>n;for(int i = 1; i <= n; i++){cin>>m>>pre;for(int j = 2; j <= m; j++){cin>>tmp;G[pre].push_back(tmp);G[tmp].push_back(pre);line[pre][tmp] = i;line[tmp][pre] = i;pre = tmp;}}cin>>k;for(int i = 1; i <= k; i++){cin>>a>>b;//memset(vis,0,sizeof(vis));minCnt = 1e9, minTrans = 1e9;tempath.clear();  tempath.push_back(a);vis[a] = 1;dfs(a,b,0);vis[a] = 0;//memsetif(minCnt == 1e9) {printf("Sorry, no line is available.\n");continue;}cout<<minCnt<<"\n";int preLine = 0, preTrans = a;//上次的线路,以及转乘点for(int j = 1; j < path.size(); j++){if(line[path[j-1]][path[j]]!=preLine){if(preLine!=0)printf("Go by the line of company #%d from %04d to %04d.\n", preLine, preTrans, path[j-1]);preLine = line[path[j-1]][path[j]];preTrans = path[j-1];}}printf("Go by the line of company #%d from %04d to %04d.\n", preLine, preTrans, b);}return 0;
}

L3-015

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50;int n, T0, ok;
int e[maxn][maxn], vis[maxn];
vector<int>q;
void dfs(int u, int k){for(int i = 1; i <= n; i++){int flag = 0;//剩余队伍不存在战胜第一只队伍for(int j = 1; j <= n; j++){if(!vis[j] && e[j][T0]){flag = 1; break;}}if(flag && !ok && !vis[i] && e[u][i]){vis[i] = 1;  q.push_back(i);if(k==n-1 && e[i][T0]){ok = 1;for(int j = 0; j < q.size(); j++){if(j!=0)cout<<" "; cout<<q[j];}}else{dfs(i,k+1);}vis[i] = 0;  q.pop_back();}}
}int main(){cin>>n;  cin.get();for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){char ch;  cin>>ch;if(ch=='W')e[i][j] = 1;if(ch=='L')e[j][i] = 1;}cin.get();}for(int i = 1; i <= n; i++){//另i为队首vis[i] = 1;  q.push_back(i);T0 = i;  dfs(i,1); if(ok)return 0;vis[i] = 0;  q.pop_back();}cout<<"No Solution";return 0;
}

L3-016

#include<bits/stdc++.h>
using namespace std;struct node{int l=-1, r=-1, fa=-1, h;};
map<int,node>Tree;
void insert(int u, int h, int v){if(u==-1)return ;int uu = (v<u ? Tree[u].l : Tree[u].r);if(uu!=-1){insert(uu,h+1,v);}else{if(v<u)Tree[u].l = v;else Tree[u].r = v;Tree[v].fa = u;Tree[v].h = h;}
}bool judge(int u, int a, int b, string lk){if(lk=="root")return u==a;;if(Tree.find(a)==Tree.end() || Tree.find(b)==Tree.end())return false;if(lk=="siblings")return Tree[a].fa==Tree[b].fa;if(lk=="parent")return Tree[a].l==b || Tree[a].r==b;if(lk=="left")return Tree[b].l == a;if(lk=="right")return Tree[b].r == a;if(lk=="level")return Tree[a].h==Tree[b].h;
}int main(){int n, rt, t;cin>>n>>rt; //rt是根for(int i = 2; i <= n; i++){cin>>t;insert(rt,1,t);}int m, a=0, b=0;  cin>>m;for(int i = 1; i <= m; i++){string s, lk;  cin>>a>>s;if(s=="and"){cin>>b>>s>>s;if(s=="siblings")lk = s;else cin>>s>>s>>lk;}else{cin>>s>>lk;if(lk=="parent")cin>>s>>b;else if(lk!="root")cin>>s>>s>>b;}if(judge(rt,a,b,lk))cout<<"Yes\n";else cout<<"No\n";}return 0;
}

L3-017

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;struct seg{int x, y;}sg[maxn];
bool cmp(seg a, seg b){return a.y!=b.y?a.y<b.y:a.x<b.x;}LL rmq[maxn<<2], tag[maxn<<2], c[maxn];
#define lch p<<1
#define rch p<<1|1
void pushdown(int p){if(tag[p]){tag[lch] += tag[p], tag[rch]+=tag[p];rmq[lch] += tag[p], rmq[rch]+=tag[p];tag[p] = 0;}
}
void pushup(int p){rmq[p] = min(rmq[lch], rmq[rch]);
}
void build(int p, int l, int r){tag[p] = 0;if(l==r){rmq[p] = c[l];return ;}else{int m = l+r>>1;build(lch,l,m);build(rch,m+1,r);pushup(p);}
}
void update(int p, int l, int r, int L, int R, int v){if(l>R || r<L)return ;if(L<=l && r<=R){rmq[p] += v;  tag[p] += v;return ;}pushdown(p);int mid = l+r>>1;update(lch,l,mid,L,R,v);update(rch,mid+1,r,L,R,v);pushup(p);
}
LL query(int p, int l, int r, int L, int R){if(l>R || r<L)return (1ll<<60);if(L<=l && r<=R)return rmq[p];pushdown(p);LL mid = l+r>>1, ans = 1ll<<60;ans = min(ans, query(lch,l,mid,L,R));ans = min(ans, query(rch,mid+1,r,L,R));return ans;
}int main(){int n, q;cin>>n>>q;for(int i = 1; i < n; i++)cin>>c[i];build(1,1,n-1); //1-(n-1)号城市分别对应i与i+1的边for(int i = 1; i <= q; i++){cin>>sg[i].x>>sg[i].y;if(sg[i].x>sg[i].y)swap(sg[i].x,sg[i].y);}sort(sg+1,sg+q+1,cmp);LL ans = 0;for(int i = 1; i <= q; i++){//cout<<sg[i].x+1<<" "<<sg[i].y<<" ";LL res = query(1,1,n-1,sg[i].x+1,sg[i].y);//因为编号从0开始,所以x+1。//cout<<res<<"\n";ans += res;if(res)update(1,1,n-1,sg[i].x+1,sg[i].y,-res);}cout<<ans<<endl;return 0;
}

L3-018

#include<bits/stdc++.h>
using namespace std;
const int inf = 1e9+10;
const int maxn = 110;struct point{ int x, y;  double dis;};
bool operator!=(point a, point b){return a.x!=b.x||a.y!=b.y;}
bool operator==(point a, point b){return a.x==b.x&&a.y==b.y;}int n, m;
double sc[maxn][maxn];//分数
point s, t;
void input(){cin>>n>>m;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)cin>>sc[i][j];cin>>s.y>>s.x>>t.y>>t.x;s.x++;s.y++;t.x++;t.y++;s.dis = sc[s.x][s.y];
}int flag;//1上半部分,0下半部分
double f[maxn][maxn]; //到i,j为止的最小值
int dir[][2]= {{0,1},{1,0},{-1,0},{0,-1},{-1,-1},{1,-1},{-1,1},{1,1}}; //上下左右+前后左右
int cross(point a,point b,point p){//三角形行列式公式,判断三点是否在一个直线上return (b.x-a.x)*(p.y-a.y)-(p.x-a.x)*(b.y-a.y);
}
bool check(point p){//检查p是否合法(越界)if(p.x<1||p.x>n||p.y<1||p.y>m)return false;//越界if(flag && p!=s&&p!=t && cross(s,t,p)<=0)return false;//1:上半部分但点在下面(起点终点不算)if(!flag && p!=s&&p!=t && cross(s,t,p)>=0)return false;//2.下半部分但点在上面if(p.dis>=f[p.x][p.y])return false;//不是最小值return true;
}
void bfs(){//initqueue<point>q;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)f[i][j] = inf;//searchif(check(s)){f[s.x][s.y] = s.dis;q.push(s);}while(q.size()){point now = q.front(); q.pop();point next;for(int i = 0; i < 8; i++){next.x=now.x+dir[i][0];next.y=now.y+dir[i][1];if(i<4)next.dis = f[now.x][now.y]+sc[next.x][next.y];else next.dis=f[now.x][now.y]+sc[next.x][next.y]+(sc[next.x][next.y]+sc[now.x][now.y])*(sqrt(2)-1);if(check(next)){f[next.x][next.y] = next.dis;q.push(next);}}}
}int main(){input();double ans = 0;flag = 1; bfs(); ans += f[t.x][t.y];//搜上面flag = 0; bfs(); ans += f[t.x][t.y];//搜下面ans -= sc[s.x][s.y]+sc[t.x][t.y];//重复printf("%.2f\n",ans);return 0;
}

L3-019

#include<bits/stdc++.h>
using namespace std;//判断语句块类型
int judge(string dat, int i){//WA3:当前位置是if并且不是在字符串内if(dat.find("if", i)==i && (dat[i+2]==' '||dat[i+2]=='('))return 2;if(dat.find("for",i)==i && (dat[i+3]==' ' ||dat[i+3]=='('))return 3;if(dat.find("while",i)==i && (dat[i+5]==' '||dat[i+5]=='('))return 5;if(dat.find("else",i)==i && dat[i+4]==' ')return 4;return 0;//普通语句
}
//输出前删除多余空格, 并输出当前对应的空格
void erase_space(string dat,int &i){while(dat[i]==' ')i++;}
void print_space(int sp){for(int i=0;i<sp;i++)putchar(' ');}int main(){string dat;  getline(cin,dat);//处理int main()  找i和)输出int l = dat.find('i',0), r = dat.find(')',0);cout<<dat.substr(l,r-l+1)<<"\n{\n";//处理其他,按照行分类int tmp, space = 2;//语句类型,空格数int flag, debt=0;//单句标记,层数(补全缺少的})for(int i = dat.find('{')+1,j=0,k; i < dat.size(); ){erase_space(dat,i);//删除每行前的空格if(dat[i]=='{' || dat[i]=='}'){if(dat[i]=='{'){print_space(space);printf("{\n");space += 2;i++;continue;}else{space -= 2;print_space(space);printf("}\n");i++;if(space==0)break;//main的}输完就结束了//【重复】单句特判erase_space(dat,i);while(debt && judge(dat,i)!=4){space -= 2;print_space(space);printf("}\n");debt--;}}}else if((tmp=judge(dat,i))){print_space(space);//处理for,while,if,+()或者elseif(tmp==4){printf("else");k = i+3;}else{cout<<dat.substr(i,tmp)<<" ";i += tmp;erase_space(dat, i);//考虑if()中也有()条件的情况k = i; int t = 0;while(1){if(dat[k]=='(')t++;if(dat[k]==')')t--;if(!t)break;k++;}cout<<dat.substr(i,k-i+1);}//预处理{}的内容,考虑单句特判int m = k+1;erase_space(dat,m);if(dat[m] != '{'){//单句标记printf(" {\n");flag = 1;debt++;i = m;}else{printf(" {\n");flag = 0;i = m+1;}space += 2;}else{//普通语句int ed = dat.find(';', i);print_space(space);cout<<dat.substr(i,ed-i+1)<<"\n";i = ed+1;//这是单句内的语句if(flag && debt){space -= 2;print_space(space);printf("}\n");debt--;//【重复】单句特判erase_space(dat,i);while(debt && judge(dat,i)!=4){space -= 2;print_space(space);printf("}\n");debt--;}}}}return 0;
}

L3-020

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
LL f[maxn][5];
int main(){string s;  cin>>s; s = "0"+s;//从1开始f[0][0] = 1;for(int i = 1; i < s.size(); i++){for(int j = 0; j <= 3; j++){//删0-3个f[i][j] = f[i-1][j]+f[i-1][j-1];//第i个删还是不删for(int k=i-1; k>=1 && (i-k)<=j; k--){//去重if(s[k]==s[i]){//如果当前字符一样,那么前面的重复统计了f[i][j] -= f[k-1][j-(i-k)];break;}}}}LL ans = 0;for(int i = 0; i <= 3; i++)ans += f[s.size()-1][i];cout<<ans<<endl;return 0;
}

L3-021

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e5+10;struct point{LL x, y;}pp[maxn], tmp[maxn];
bool cmp(point a, point b){return a.x*b.y>a.y*b.x;}int main(){int n;  cin>>n;for(int i = 0; i < n; i++)cin>>pp[i].x>>pp[i].y;double ans = 1e18;for(int i = 0; i < n; i++){int cc = 0;for(int j = 0; j < n; j++){if(i==j)continue;tmp[cc].x = pp[j].x-pp[i].x;tmp[cc].y = pp[j].y-pp[i].y;cc++;}sort(tmp,tmp+cc,cmp);for(int j = 0; j < cc; j++)ans=min(ans,abs(0.5*(tmp[j].x*tmp[(j+1)%cc].y-tmp[(j+1)%cc].x*tmp[j].y)));}printf("%.3f\n",ans);return 0;
}

L3-022

#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
const int inf = 1e9+10;
int G[maxn][maxn];
vector<int>st[maxn]; int ed[maxn], vis[maxn];
void dfs(int u){for(int i = 0; i < st[u].size(); i++){int v = st[u][i];if(!vis[v]){vis[v] = 1;dfs(v);}}
}
int main(){//inputint n, m, k;  cin>>n>>m>>k;for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)G[i][j] = inf;for(int i = 1; i <= m; i++){int a, b, dis;cin>>a; ed[a] = 1;while(cin>>dis>>b){G[a][b] = min(G[a][b], dis);G[b][a] = min(G[b][a], dis);a = b;if(getchar()=='\n')break;}ed[a] = 1;}//solvefor(int k = 1; k <= n; k++)//Floydfor(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)if(i!=j)G[i][j] = min(G[i][j],G[i][k]+G[k][j]);for(int i = 1; i <= n; i++){//从点i出发map<int,int>cost;//各种费用能到的最远距离for(int j = 1; j <= n; j++){//遍历到每个点的费用去更新距离if(G[i][j]==inf)continue;cost[2+G[i][j]/k] = max(cost[2+G[i][j]/k],G[i][j]);}for(int j = 1; j <= n; j++){//更新点i能到达的最远点或者端点if(G[i][j]==cost[2+G[i][j]/k] || i!=j&&ed[j]&&G[i][j]!=inf){st[i].push_back(j);}}}int q;  cin>>q;for(int i = 1; i <= q; i++){int x;  cin>>x;memset(vis,0,sizeof(vis));vis[x] = 1;dfs(x);for(int j = 1; j <= n; j++)if(vis[j])st[x].push_back(j);sort(st[x].begin(), st[x].end());st[x].erase(unique(st[x].begin(), st[x].end()), st[x].end());for(int j = 0; j < st[x].size(); j++){if(j!=0)cout<<" ";cout<<st[x][j];}cout<<"\n";}return 0;
}

L3-023

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4+10;struct node{int op, left, right; //运算符和数值double val; //当前节点的值int post;  //后继节点的
}a[maxn];
map<int,map<int,map<int,double>>>f;//记忆化数组//第一个参数为结点,第二个参数决定是否求导,第三个参数是对谁求导
double calc(int nd, int key, int p){if(f[nd][key][p])return f[nd][key][p];int id = a[nd].op;if(id==0)return f[nd][key][p] = (key == 0 ? a[nd].val : (nd == p ? 1 : 0)); if(id==1)return f[nd][key][p] = calc(a[nd].left, key, p) + calc(a[nd].right, key, p); if(id==2)return f[nd][key][p]= calc(a[nd].left, key, p) - calc(a[nd].right, key, p); if(id==3)return f[nd][key][p] = (key ? calc(a[nd].left, key, p) * calc(a[nd].right, 0, p) + calc(a[nd].left, 0, p) * calc(a[nd].right, key, p) : calc(a[nd].left, key, p) * calc(a[nd].right, key, p)); if(id==4)return f[nd][key][p]=(key ? exp(calc(a[nd].left, 0, p)) * calc(a[nd].left, key, p) : exp(calc(a[nd].left, key, p)));if(id==5)return f[nd][key][p] = (key ? 1 / (calc(a[nd].left, 0, p)) * (calc(a[nd].left, key, p)) : log(calc(a[nd].left, key, p)));if(id==6)return f[nd][key][p] = (key ? cos(calc(a[nd].left, 0, p)) * calc(a[nd].left, key, p) : sin(calc(a[nd].left, key, p)));
}int main(){int n;  cin>>n;for(int i = 0; i < n; i++){cin>>a[i].op;if(a[i].op==0){cin>>a[i].val;}else if(a[i].op<=3){cin>>a[i].left>>a[i].right;a[a[i].left].post = 1;a[a[i].right].post = 1;}else{cin>>a[i].left;a[a[i].left].post = 1;}}int ed = 0, ok=0;while(a[ed].post)ed++;printf("%0.3lf\n",calc(ed,0,-1));for(int i = 0; i < n; i++){if(a[i].op==0){if(ok)cout<<" ";printf("%0.3lf",calc(ed,1,i));ok = 1;}}return 0;
}

【CCCC】PAT : 团体程序设计天梯赛-练习集 L3 答案(01-23)相关推荐

  1. PAT : 团体程序设计天梯赛-练习集 L3 答案即比赛技巧

    知识点分类(23): 1.搜索模拟(5):BFS,DFS,最短路,路径打印 2.计算几何(5):找规律,斜率计算,极角排序,三角形面积,三点共线,凸包 3.数据结构(5):栈,并查集,二叉树,堆,线段 ...

  2. 【CCCC】PAT : 团体程序设计天梯赛-练习集 L2 答案,题解,附代码

    [CCCC]PAT : 团体程序设计天梯赛-练习集 L2 答案 鉴定完毕,全部水题 ヾ(•ω•`)o 知识点分类(32): 1.树锯结构(9):二叉树的存储,编号,遍历顺序转换,求深度,底层节点,从底 ...

  3. 【CCCC】PAT : 团体程序设计天梯赛-练习集 L1 答案

    [CCCC]PAT : 团体程序设计天梯赛-练习集 L1 答案 鉴定完毕,全部水题 ヾ(•ω•`)o 标号 标题 分数 通过数 提交数 通过率 L1-001 Hello World 5 46779 1 ...

  4. PAT 团体程序设计天梯赛-练习集 题解(凑零钱,堆栈,社交集群)

    开始准备cccc(cry)天梯赛了,第一周训练题,把官网挂出的训练题刷完了,对pat有了一点点的熟悉感. L1-1  就不说了... L1-2 打印沙漏 一个变量保存空格数,一个变量保存沙漏符号数,打 ...

  5. PAT : 团体程序设计天梯赛-练习集L1 个人题解

    另把天梯赛所有题解内容全部打包成了一个文档,可以自行下载:https://download.csdn.net/download/daixinliangwyx/11170075 L1-001 Hello ...

  6. PAT——团体程序设计天梯赛-练习集(10分题集)Python 3

    这个博客里面全部都是10分题的合集 活着就是为了改变世界,难道还有其他原因吗?-- 乔布斯 L1-008 求整数段和 (10分) 给定两个整数A和B,输出从A到B的所有整数以及这些数的和. 输入格式: ...

  7. L2-005 集合相似度-PAT团体程序设计天梯赛GPLT

    题目来源:团体程序设计天梯赛-练习集 题目地址:L2-005 集合相似度 题目大意 给定 nnn 个集合,然后有 kkk 次询问,每次询问都要求出 Nc/Nt×100%N_c / N_t \times ...

  8. PTA团体程序设计天梯赛-练习集(3)

    PTA团体程序设计天梯赛-练习集 L1-001 Hello World (5 分) 这道超级简单的题目没有任何输入. 你只需要在一行中输出著名短句"Hello World!"就可以 ...

  9. PTA团体程序设计天梯赛-练习集

    PTA团体程序设计天梯赛-练习集 L1-024 后天 L1-025 正整数A+B L1-026 I Love GPLT L1-027 出租 L1-029 是不是太胖了 L1-030 一帮一 L1-03 ...

最新文章

  1. SpringBoot整合MyBatis详细教程~
  2. WebSphere Application Server中manageprofiles的使用
  3. 图像处理(十二)图像融合(1)Seamless cloning泊松克隆-Siggraph 2004
  4. hp服务器重置bmc,HP iLO 登录用户名与 BMC 用户名不一致导致 ipmitool 无法修改用户名...
  5. python isalpha函数用法_python中string模块各属性以及函数的用法
  6. SonarQube搭建和使用教程
  7. webpack 命令
  8. Python垃圾回收机制 总结
  9. 用jmap和jps查看对象数量
  10. 雅虎相册批量下载v3.0 公布!支持相册主人登录 欢迎大家试用
  11. android10项目编译出错,android studio编译项目出错
  12. 简述固定资产的全生命周期管理流程
  13. 昌吉学院计算机工程系毕业后安排工作嘛,经济贸易分院成功举办昌吉学院与我院本科教学与学生工作对接会...
  14. 减少2021年度汇算清缴补税
  15. 一文带你浅入浅出Keepalived
  16. for循环的执行顺序,i++和++i
  17. JdbcTempalte添加修改删除查询批量操作
  18. 淘宝(SpringBoot自动装配原理)
  19. CentOS6云服务器磁盘扩容方案
  20. 无线蓝牙耳机充电仓充电_无线充电是一场灾难,正在等待发生

热门文章

  1. 离散型概率分布的抽样
  2. 书法的艺术 —— 大家的作品
  3. 数学归纳法的相关证明
  4. for 循环 and while 循环(二)
  5. python日常能做什么-Python除了做AI、还能干啥?
  6. python函数定义及调用-Python函数的基本定义和调用以及内置函数
  7. python适合自学编程吗-孩子学编程选Scratch还是Python
  8. python和c++哪个好-c语言和python哪个好入门?
  9. 语音识别基础知识_语音识别_CTI论坛
  10. php10天速成培训,十天学会php之第九天