PAT2021秋季备考总结
- 考纲原文
- 刷题总结
- 模拟题
- 数学问题
- 字符串处理题
- STL模板题
- 排序题
- 哈希散列题
- 链表题
- 二叉树 相关题
- 树 相关题
- 1138. Postorder Traversal (25) [树的遍历,前序中序转后序]
- 1053. Path of Equal Weight (30) [树的遍历]
- 1079. Total Sales of Supply Chain (25) [DFS,BFS,树的遍历]
- 1086. Tree Traversals Again (25) [树的遍历]
- 1090. Highest Price in Supply Chain (25) [树的遍历]
- 1094. The Largest Generation (25) [BFS,DFS,树的遍历]
- 1102. Invert a Binary Tree (25) [树的遍历]
- 1106. Lowest Price in Supply Chain (25) [DFS,BFS,树的遍历]
- 1115. Counting Nodes in a BST (30) [⼆叉树的遍历,DFS]
- 1119. Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]
- 1127. ZigZagging on a Tree (30) [中序后序建树,层序遍历]
- 1138. Postorder Traversal (25) [树的遍历,前序中序转后序]
- 1151. LCA in a Binary Tree (30) [树的遍历,LCA算法]
- 1119. Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]
- 二叉查找树(BST/AVL) 相关题
- 并查集 相关题
- 堆 相关题
- 图 相关题
- 图的遍历 相关题
- Dijkstra 相关题
- 水题
- 近五场考试
- 基础数据结构模板
- 基础算法
- PAT其余题目浏览
考纲原文
在达到乙级要求的基础上,还要求:
- 具有充分的英文阅读理解能力;
- 理解并掌握基础数据结构,包括:线性表、树、图;
- 理解并熟练编程实现经典高级算法,包括哈希映射、并查集、最短路径、拓扑排序、关键路径、贪心、深度优先搜索、广度优先搜索、回溯剪枝等;
- 具备较强的问题抽象和建模能力,能实现对复杂实际问题的模拟求解。
刷题总结
模拟题
1153. Decode Registration Card of PAT (25) [模拟,排序,map]
#include "iostream"
#include "algorithm"
#include "unordered_map"
#include "vector"
using namespace std;
struct node
{
string t;
int value;
};
bool cmp(const node &a,const node &b)
{
if(a.value!=b.value) return a.value > b.value;
else return a.t < b.t;
}
int main()
{
int n,m;
cin>>n>>m;
vector<node> v(n);
for(int i=0; i<n; i++) cin>>v[i].t>>v[i].value;
for(int i=1; i<=m; i++)
{
int num,cnt = 0,total = 0;
vector<node> ans;
string cmd;
cin>>num>>cmd;
printf("Case %d: %d %s\n",i,num,cmd.c_str());
if(num==1)
{
for(auto j:v) if(j.t[0]==cmd[0]) ans.push_back(j);
}
else if(num==2)
{
for(auto j:v)
{
if(j.t.substr(1,3)==cmd)
{
cnt++;
total += j.value;
}
}
}
else if(num==3)
{
unordered_map<string,int> dn;
for(auto j:v)
{
if(j.t.substr(4,6)==cmd) dn[j.t.substr(1,3)]++;
}
for(auto it = dn.begin(); it!=dn.end(); it++) ans.push_back(node{it->first,it->second});
}
sort(ans.begin(),ans.end(),cmp);
if(((num==1||num==3)&&ans.size()==0)||(num==2&&cnt==0)) printf("NA\n");
else if(num==1||num==3) for(auto j:ans) printf("%s %d\n",j.t.c_str(),j.value);
else if(num==2) printf("%d %d\n",cnt,total);
}
return 0;
}
//Summary:
/*
1.字符串能解决的问题,尽量不要转成数字拆解
如本题的node结构体,其实不需要搞得这么复
杂
2.若已知问题规模,可考虑在初始化时就指定好
vector的大小
3.特殊性输出可考虑在最后统一进行,避免每个
case里面都有判断的情况
4.不涉及排序,unordered_map永远优先
5.增强型for循环更简便
6.可考虑构造一个抽象类型,如此便于cmp复用。
如本例中,type 1和3都涉及排序,但本质上都是
一个node里两个成员的排序,且排序逻辑也相同。
7.cmp函数用引用传参好习惯。
*/
/*
#include "iostream"
#include "algorithm"
#include "map"
#include "vector"
using namespace std;
struct node
{
string id;
char cls;
int site,date,tid,score;
};
struct snode
{
int site;
int ns;
};
bool cmp(snode a,snode b)
{
if(a.ns!=b.ns) return a.ns > b.ns;
else return a.site < b.site;
}
bool cmp1(node a,node b)
{
if(a.score!=b.score) return a.score>b.score;
else return a.id<b.id;
}
int main()
{
int n,m,score;
cin>>n>>m;
vector<node> v,ans;
vector<node> va,vb,vt;
string id;
map<int,int> mpst;
int a[1010];
for(int i=0; i<n; i++)
{
cin>>id>>score;
node tmp = node{id,id[0],stoi(id.substr(1,3)),stoi(id.substr(4,6))
,stoi(id.substr(10,3)),score};
v.push_back(tmp);
//query by class
if(tmp.cls=='A') va.push_back(tmp);
else if(tmp.cls=='B') vb.push_back(tmp);
else vt.push_back(tmp);
//query by site
mpst[tmp.site]++;
a[tmp.site] += tmp.score;
}
getchar();
string cmd;
for(int i=0; i<m; i++)
{
bool flag = false;
cmd = "";
getline(cin,cmd);
cout<<"Case "<<i+1<<": "<<cmd<<endl;
if(cmd[0]=='1')
{
char level = cmd[2];
vector<node> ans;
if(level=='A') ans = va;
else if(level=='B') ans = vb;
else ans = vt;
if(ans.size()==0)
{
printf("NA\n");
continue;
}
sort(ans.begin(),ans.end(),cmp1);
for(int j=0; j<ans.size(); j++)
{
printf("%s %d\n",ans[j].id.c_str(),ans[j].score);
}
}
else if(cmd[0]=='2')
{
int site = stoi(cmd.substr(2,3));
if(mpst[site]==0)
{
printf("NA\n");
continue;
}
printf("%d %d\n",mpst[site],a[site]);
}
else if(cmd[0]=='3')
{
int date = stoi(cmd.substr(2,6));
vector<snode> sv;
map<int,int> dn;
for(int j=0; j<v.size(); j++)
{
if(v[j].date == date)
{
dn[v[j].site]++;
}
}
if(dn.empty())
{
printf("NA\n");
continue;
}
for(auto it=dn.begin(); it!=dn.end(); it++)
{
sv.push_back(snode{it->first,it->second});
}
sort(sv.begin(),sv.end(),cmp);
for(int j=0; j<sv.size(); j++)
{
printf("%d %d\n",sv[j].site,sv[j].ns);
}
}
}
return 0;
}
*/
数学问题
1132. Cut Integer (20) [数学问题]
#include "iostream"
#include "string"
using namespace std;
int main(){
int n;
double num, numA, numB;
string s, sa, sb;
cin >> n;
for (size_t i = 0; i < n; i++){
cin >> s;
num = stod(s);
sa = s.substr(0, s.length() / 2);
sb = s.substr(s.length() / 2, s.length() / 2);
numA = stod(sa);
numB = stod(sb);
double res = num / (numA*numB);
if (res == (int)res)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}
字符串处理题
1140. Look-and-say Sequence (20) [字符串处理]
#include "algorithm"
#include "iostream"
using namespace std;
int main()
{
int n;
string d;
cin>>d>>n;
string res = d+"1";
string nRes = "";
int cnt = 1;
if(n==1)
{
cout<<d<<endl;
return 0;
}
else if(n==2)
{
cout<<res<<endl;
return 0;
}
n -= 2;
while(n--)
{
//1 11 12 1121 122111 112213 12221131 1123123111
nRes = "";
for(int i=0; i<res.length(); i++)
{
if(res[i]==res[i+1])
{
cnt++;
continue;
}
nRes += res[i];
nRes.append(to_string(cnt));
cnt = 1;
}
res = nRes;
}
cout<<nRes<<endl;
return 0;
}
1152. Google Recruitment (20) [字符串处理]
#include "iostream"
#include "algorithm"
#include "math.h"
using namespace std;
bool isPrime(string sNum)
{
int num = stoi(sNum);
if(num==1||num==0) return false;
else if(num==2) return true;
for(int i=2; i<sqrt(num)+1; i++)
{
if(num%i==0) return false;
}
return true;
}
int main()
{
int l,n;
cin>>l>>n;
string str;
cin>>str;
for(int i=0; i<=l-n; i++)
{
string tmp = str.substr(i,n);
if(isPrime(tmp))
{
cout<<tmp<<endl;
return 0;
}
}
cout<<"404"<<endl;
return 0;
}
STL模板题
1095.Cars on Campus (30) [map的⽤法,排序]
#include "iostream"
#include "algorithm"
#include "vector"
#include "map"
#include "cstring"
#include "set"
#include "unordered_map"
using namespace std;
struct node
{
char plate[10];
int time,state;
};
bool cmp(const node &a,const node &b)
{
if(strcmp(a.plate,b.plate)!=0) return strcmp(a.plate,b.plate)<0;
else return a.time<b.time;
}
bool cmp1(const node &a,const node &b)
{
return a.time<b.time;
}
int main()
{
int n,m;
scanf("%d%d\n", &n, &m);
vector<node> v(n),ans;
int hh,mm,ss;
for(int i=0; i<n; i++)
{
char temp[10];
scanf("%s %d:%d:%d %s\n",&v[i].plate,&hh,&mm,&ss,temp);
v[i].time = hh*3600+mm*60+ss;
v[i].state = strcmp(temp,"in")==0?1:-1;
}
sort(v.begin(),v.end(),cmp);
map<string,int> stay;
int maxTime = -1;
for(int i=0; i<n-1; i++)
{
if(strcmp(v[i].plate,v[i+1].plate)==0)
{
if(v[i].state==1&&v[i+1].state==-1)
{
ans.push_back(v[i]);
ans.push_back(v[i+1]);
stay[v[i].plate] += v[i+1].time - v[i].time;
if(stay[v[i].plate]>maxTime) maxTime = stay[v[i].plate];
}
}
}
sort(ans.begin(),ans.end(),cmp1);
vector<int> cnt(ans.size());
for(int i=0; i<ans.size(); i++)
{
if(i==0) cnt[0] += ans[i].state;
else cnt[i] = cnt[i-1]+ans[i].state;
}
for(int i=0; i<m; i++)
{
int time,j;
int tmpIdx = 0;
scanf("%d:%d:%d",&hh,&mm,&ss);
time = hh*3600+mm*60+ss;
for(j=tmpIdx; j<ans.size(); j++)
{
if(ans[j].time>time)
{
printf("%d\n", cnt[j - 1]);
break;
}
else if(j==ans.size()-1) cout<<cnt[j]<<endl;
}
tmpIdx = j;
}
for(auto &v:stay){
if(v.second==maxTime) printf("%s ",v.first.c_str());
}
printf("%02d:%02d:%02d\n",maxTime/3600,(maxTime/60)%60,maxTime%60);
return 0;
}
1137. Final Grading (25) [map映射,排序]
#include "iostream"
#include "map"
#include "vector"
#include "algorithm"
using namespace std;
struct node
{
string name;
int gp,gm,gf,g;
};
bool cmp(node &a,node &b)
{
if(a.g!=b.g) return a.g > b.g;
else if(a.name!=b.name) return a.name < b.name;
}
int main()
{
int m,n,p;
int cnt = 1;
string s;
int score;
cin>>m>>n>>p;
map<string,int> idx;
vector<node> v,ans;
node tmp;
for(int i=0; i<m; i++)
{
cin>>s>>score;
if(score>=200)
{
tmp = {s,score,-1,-1,-1};
v.push_back(tmp);
idx[s] = cnt++;
}
}
for(int i=0; i<n; i++)
{
cin>>s>>score;
if(idx[s]>0)
{
tmp = v[idx[s]-1];
tmp = {s,tmp.gp,score,-1,-1};
v[idx[s]-1] = tmp;
}
}
for(int i=0; i<p; i++)
{
cin>>s>>score;
if(idx[s]>0)
{
tmp = v[idx[s]-1];
tmp = {s,tmp.gp,tmp.gm,score,-1};
v[idx[s]-1] = tmp;
}
}
for(int i=0; i<v.size(); i++)
{
if(v[i].gm > v[i].gf)
v[i].g = (v[i].gm*0.4+v[i].gf*0.6+0.5);
else v[i].g = v[i].gf;
if(v[i].g>=60)
ans.push_back(v[i]);
}
sort(ans.begin(),ans.end(),cmp);
for(int i=0; i<ans.size(); i++)
{
printf("%s %d %d %d %d\n",ans[i].name.c_str(),ans[i].gp,ans[i].gm,ans[i].gf,ans[i].g);
}
return 0;
}
//Summary:
/*
1.map里不要做复杂的映射,不同数据结构应当做到各司其职。
如本题中通过map来维护id,通过vector来存储数据,如果构造map<str,node>
型的映射,对于后续的排序处理会很麻烦。总之,尽可能降
低不同ds之间的耦合度。
2.四舍五入要再括号里+0.5
3.vector里的数据可以直接修改,不用非得像map一样,先取后改再存。
e.g.:
tmp = v[idx[s]-1];
tmp = {s,tmp.gp,score,-1,-1};
v[idx[s]-1] = tmp;
可改写成:
tmp = v[idx[s]-1];
tmp.gm = score;
*/
1121. Damn Single (25) [set的应⽤]
#include "iostream"
#include "vector"
#include "set"
#include "string"
#include "map"
using namespace std;
map<string, string> cp;
set<string> peo;
int main()
{
int n;
cin >> n;
for (size_t i = 0; i < n; i++)
{
string a, b;
cin >> a >> b;
cp[a] = b;
cp[b] = a;
}
int m;
cin >> m;
for (size_t i = 0; i < m; i++)
{
string a;
cin >> a;
peo.insert(a);
}
vector<string> v;
for (auto it = peo.begin(); it != peo.end();it++)
{
if (cp[*it] == "" || peo.count(cp[*it]) == 0)
v.push_back(*it);
}
cout << v.size() << endl;
for (size_t i = 0; i < v.size(); i++)
{
if (i != 0) cout << " ";
cout << v[i];
}
system("pause");
return 0;
}
1124. Rafle for Weibo Followers (20) [map映射]
#include "iostream"
#include "vector"
#include "string"
#include "map"
using namespace std;
map<string, bool> sta;
int main()
{
int n, m, s;
int flag = 0;
cin >> n >> m >> s;
vector<string> v;
v.resize(n + 1);
for (size_t i = 1; i <= n; i++) {
cin >> v[i];
sta[v[i]] = false;
}
for (size_t i = s; i <= n; i += m)
{
while(sta[v[i]]&&i<=n) i++;
cout << v[i] << endl;
sta[v[i]] = true;
flag = 1;
}
if (flag == 0) cout << "Keep going..." << endl;
system("pause");
return 0;
}
1129. Recommendation System (25) [set应⽤,运算符重载] (似乎还不会)
#include <iostream>
#include <set>
using namespace std;
int book[50001];
struct node {
int value, cnt;
bool operator < (const node &a) const {
return (cnt != a.cnt) ? cnt > a.cnt : value < a.value;
}
};
int main() {
int n, k, num;
scanf("%d%d", &n, &k);
set<node> s;
for (int i = 0; i < n; i++) {
scanf("%d", &num);
if (i != 0) {
printf("%d:", num);
int tempCnt = 0;
for (auto it = s.begin(); tempCnt < k && it != s.end(); it++) {
printf(" %d", it->value);
tempCnt++;
}
printf("\n");
}
auto it = s.find(node{ num, book[num] });
if (it != s.end()) s.erase(it);
book[num]++;
s.insert(node{ num, book[num] });
}
return 0;
}
1144. The Missing Number (20) [STL,map]
#include "iostream"
#include "map"
using namespace std;
int main()
{
int n, num = 0;
cin >> n;
map<int, int> mp;
for (size_t i = 0; i < n; i++){
int e;
cin >> e;
mp[e]++;
}
while (++num) if (mp[num] == 0) break;
cout << num << endl;
return 0;
}
排序题
1.1141. PAT Ranking of Institutions (25) [排序,map STL]
#include "iostream"
#include "algorithm"
#include "vector"
#include "map"
using namespace std;
/*
10
A57908 85 Au
B57908 54 LanX
*/
struct node
{
string name;
int tws,ns;
};
bool cmp(node a,node b)
{
if(a.tws!=b.tws) return a.tws>b.tws;
else if(a.ns!=b.ns) return a.ns<b.ns;
else if(a.name!=b.name) return a.name<b.name;
}
int main()
{
int n;
cin>>n;
string id,name;
double score;
map<string,int> cnt;
map<string,double> sum;
vector<node> ans;
for(int i=0; i<n; i++)
{
cin>>id>>score>>name;
for(int j=0; j<name.length(); j++)
{
name[j] = tolower(name[j]);
}
if(id[0]=='B') score /= 1.5;
else if(id[0]=='T') score *= 1.5;
sum[name] += score;
cnt[name]++;
}
for(auto it=cnt.begin(); it!=cnt.end(); it++)
{
ans.push_back(node{it->first,(int)sum[it->first],it->second});
}
sort(ans.begin(),ans.end(),cmp);
cout<<ans.size()<<endl;
int rk = 1;
int tmp = ans[0].tws;
for(int i=0;i<ans.size();i++){
if(ans[i].tws<tmp) rk = i+1;
printf("%d %s %d %d\n",rk,ans[i].name.c_str(),ans[i].tws,ans[i].ns);
tmp = ans[i].tws;
}
return 0;
}
//Summary:
/*
1.能用一个结构体解决的就用一个
2.map就能处理的数据可以多用几个map
3.不要用太多vector,尤其是有关系的vector,不好维护
4.涉及小数乘除法的,下意识要用double
*/
哈希散列题
1145. Hashing – Average Search Time (25) [哈希映射,哈希表,平⽅探测法]
#include <iostream>
#include <vector>
using namespace std;
bool isprime(int n)
{
if (n <= 1) return false;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
int main()
{
int tsize, n, m, a;
scanf("%d %d %d", &tsize, &n, &m);
while(!isprime(tsize)) tsize++;
vector<int> v(tsize);
for (int i = 0; i < n; i++)
{
scanf("%d", &a);
int flag = 0;
for (int j = 0; j < tsize; j++)
{
int pos = (a + j * j) % tsize;
if (v[pos] == 0)
{
v[pos] = a;
flag = 1;
break;
}
}
if (!flag) printf("%d cannot be inserted.\n", a);
}
int ans = 0;
for (int i = 0; i < m; i++)
{
scanf("%d", &a);
for (int j = 0; j <= tsize; j++)
{
ans++;
int pos = (a + j * j) % tsize;
if (v[pos] == a || v[pos] == 0) break;
}
}
printf("%.1lf\n", ans * 1.0 / m);
return 0;
}
1134. Vertex Cover (25) [hash散列]
#include "iostream"
#include "vector"
#include "set"
using namespace std;
vector<pair<int, int> > v;
int main()
{
int n, m, a, b;
cin >> n >> m;
for (size_t i = 0; i < m; i++)
{
cin >> a >> b;
v.push_back({ a, b });
}
int t;
cin >> t;
for (size_t i = 0; i < t; i++)
{
cin >> m;
int flag = 0;
set<int> vset;
vector<int> hashTb(n,0);
for (size_t j = 0; j < m; j++){
int e;
cin >> e;
vset.insert(e);
}
for (auto k : v) {
int cnt = 0;
if (!vset.count(k.first)){
cnt++;
}
if (!vset.count(k.second)){
cnt++;
}
if (cnt == 2) {
flag = 1;
break;
}
}
if (flag == 0) cout << "Yes\n";
else cout << "No\n";
}
}
1149. Dangerous Goods Packaging (25) [STL的应⽤]
#include "iostream"
#include "unordered_map"
#include "string"
#include "vector"
using namespace std;
unordered_map<string, int> idx;
vector<vector<int> > goodList;
bool isSafe(int a, int b)
{
for (size_t i = 0; i < goodList[a].size(); i++)
{
if (goodList[a][i] == b) return false;
}
return true;
}
int main()
{
int n, m;
cin >> n >> m;
goodList.resize(2*n+10);
int cnt = 0;
for (size_t i = 0; i < n; i++)
{
string a, b;
cin >> a >> b;
if (idx[a] == 0) {
idx[a] = cnt++;
}
if (idx[b] == 0) {
idx[b] = cnt++;
}
goodList[idx[a]].push_back(idx[b]);
goodList[idx[b]].push_back(idx[a]);
}
for (size_t i = 0; i < m; i++)
{
int q;
cin >> q;
vector<int> tmp;
int flag = 0;
for (size_t j = 0; j < q; j++)
{
string e;
cin >> e;
if (idx[e] == 0||flag) continue;//若尚未记载,则一定安全
for (size_t k = 0; k < tmp.size(); k++)//在已有物品中逐次检查
{
if (!isSafe(tmp[k], idx[e])){
flag = 1;
break;
}
}
tmp.push_back(idx[e]);
}
if (flag) cout << "No\n";
else cout << "Yes\n";
}
system("pause");
return 0;
}
1154. Vertex Coloring (25) [set,hash]
#include "iostream"
#include "vector"
#include "unordered_set"
using namespace std;
struct edge
{
int left, right;
};
vector<edge> e;
vector<int> color;
int main()
{
int n, m;
cin >> n >> m;
color.resize(n);
for (size_t i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
e.push_back({ u, v });
}
int q;
cin >> q;
while (q--)
{
bool flag = false;
unordered_set<int> s;
for (size_t i = 0; i < n; i++) {
cin >> color[i];
s.insert(color[i]);/*并非只有边上的才纳入统计,
孤立的点也算,属读题有误问题*/
}
for (size_t i = 0; i < e.size(); i++)
{
int left = e[i].left;
int right = e[i].right;
if (color[left] == color[right]) flag = true;
if (flag) break;
}
if (flag) cout << "No" << endl;
else
{
printf("%d-coloring\n", s.size());
}
}
system("pause");
return 0;
}
链表题
1032 Sharing (25) [链表]
#include "iostream"
#include "vector"
using namespace std;
struct node
{
int adr,data,next;
} a[100010];
int main()
{
int bg1,bg2,n;
int res = -1;
scanf("%d%d%d",&bg1,&bg2,&n);
vector<node> v1,v2,ans;
int adr,next;
int cal[100010];
char data;
for(int i=0; i<n; i++)
{
cin>>adr>>data>>next;
a[adr] = {adr,data,next};
}
int begin = bg1;
for(; begin!=-1; begin = a[begin].next)
{
v1.push_back(a[begin]);
cal[begin]++;
}
begin = bg2;
for(; begin!=-1; begin = a[begin].next)
{
v2.push_back(a[begin]);
cal[begin]++;
if(cal[begin]>1) {
res = begin;
break;
}
}
if(res!=-1) printf("%05d",res);
else printf("-1");
return 0;
}
1052.Linked List Sorting (25) [链表]
#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;
struct node
{
int adr,data,next;
} a[100010];
bool cmp(node &a,node &b)
{
return a.data < b.data;
}
int main()
{
int n,begin;
int adr,data,next;
scanf("%d%d",&n,&begin);
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&adr,&data,&next);
a[adr] = {adr,data,next};
}
vector<node> v,ans;
for(; begin!=-1; begin = a[begin].next)
{
v.push_back(a[begin]);
}
sort(v.begin(),v.end(),cmp);
if(v.size())
{
printf("%d %05d\n",v.size(),v[0].adr);
for(int i=0; i<v.size()-1; i++)
printf("%05d %d %05d\n",v[i].adr,v[i].data,v[i+1].adr);
printf("%05d %d -1",v[v.size()-1].adr,v[v.size()-1].data);
}
else
{
printf("0 00000");
}
return 0;
}
//Summary:
/*
排序用algorithm头文件
排序函数里面是&
struct+vector+sort yyds
*/
1074.Reversing Linked List (25) [链表]
#include "iostream"
#include "vector"
using namespace std;
struct node
{
int adr,data,next;
} a[100010];
int main()
{
int begin,n,k;
int adr,data,next;
scanf("%d%d%d",&begin,&n,&k);
vector<node> v,ans;
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&adr,&data,&next);
a[adr] = {adr,data,next};
}
for(; begin!=-1; begin = a[begin].next)
{
v.push_back(a[begin]);
}
int remain = v.size()%k;
int dir = v.size()-remain;
for(int i=0; i<dir; i+=k)
{
for(int j=i+k-1; j>=i; j--)
{
ans.push_back(v[j]);
}
}
if(remain)
{
for(int i=dir; i<v.size(); i++)
{
ans.push_back(v[i]);
}
}
for(int i=0; i<ans.size()-1; i++)
printf("%05d %d %05d\n",ans[i].adr,ans[i].data,ans[i+1].adr);
printf("%05d %d -1\n",ans[ans.size()-1].adr,ans[ans.size()-1].data);
return 0;
}
//Summary:
/*
提交之前注意删除调试时的空行或其他信息
*/
1097. Deduplication on a Linked List (25) [链表]
#include "iostream"
#include "vector"
#include "math.h"
using namespace std;
struct node
{
int adr,data,next;
} a[100010];
bool flag[100010] = {false};
int ListTrv(vector<node> v)
{
if(v.empty()) return 0;
for(int i=0;i<v.size()-1;i++)
printf("%05d %d %05d\n",v[i].adr,v[i].data,v[i+1].adr);
printf("%05d %d -1",v[v.size()-1].adr,v[v.size()-1].data);
}
int main()
{
int begin,n,adr,data,next;
scanf("%d%d",&begin,&n);
vector<node> v,res;
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&adr,&data,&next);
a[adr] = {adr,data,next};
}
for(; begin!=-1; begin = a[begin].next)
{
if(!flag[abs(a[begin].data)])
{
v.push_back(a[begin]);
flag[abs(a[begin].data)] = true;
}else {
res.push_back(a[begin]);
}
}
ListTrv(v);
cout<<endl;
ListTrv(res);
return 0;
}
//Summary:
/*
涉及拆分成两个链表的题目,定义两个vector最好处理
输出时直接遍历两个vector。
*/
1133. Splitting A Linked List (25) [链表]
#include "iostream"
#include "vector"
using namespace std;
struct node
{
int addr,data,next;
};
int main()
{
int begin, n,k,addr,data,next;
scanf("%d%d%d",&begin,&n,&k);
node a[100010];
vector<node> v,ans;
for(int i=0; i<n; i++)
{
scanf("%d%d%d",&addr,&data,&next);
a[addr] = {addr,data,next};
}
for(; begin!=-1; begin = a[begin].next)
{
v.push_back(a[begin]);
}
for(int i=0; i<v.size(); i++)
{
if(v[i].data<0) ans.push_back(v[i]);
}
for(int i=0; i<v.size(); i++)
{
if(v[i].data>=0&&v[i].data<=k) ans.push_back(v[i]);
}
for(int i=0; i<v.size(); i++)
{
if(v[i].data>k) ans.push_back(v[i]);
}
for(int i=0; i<ans.size()-1; i++)
printf("%05d %d %05d\n",ans[i].addr,ans[i].data,ans[i+1].addr);
printf("%05d %d -1",ans[ans.size()-1].addr,ans[ans.size()-1].data);
return 0;
}
//Summary:
/*
1.排序类问题,抓住本质
提到保持原数据顺序,考虑采用多次遍历,每次提取所需数据
2.链表类问题,注意特征
若题目的链表是通过数组来表示的,则采用数据+结构体的方式对数据进行保存
尽可能不采用指针,且保存节点优先采用vector,数组要注意问题规格,不大的
情况下直接开大数组
* 输出要求正确,并不一定意味着数据本身要正确,比如该题最终采用的是直接
输出下一个数据的addr,避开了对next进行复杂的处理
3.注意输出格式
若输出固定位数,不齐部分用0补,则采用%nd方式。
4.格式化太强的,优先考虑scanf。
*/
二叉树 相关题
树 相关题
1138. Postorder Traversal (25) [树的遍历,前序中序转后序]
#include <iostream>
#include <vector>
using namespace std;
vector<int> pre, in;
bool flag = false;
void postOrder(int prel, int inl, int inr)
{
if (inl > inr || flag == true) return;
int i = inl;
while (in[i] != pre[prel]) i++;//Find the root pos
postOrder(prel+1, inl, i-1);//
postOrder(prel+i-inl+1, i+1, inr);
printf("%d", in[i]);
// flag = true;
}
//}
int main()
{
//7
//1 2 3 4 5 6 7 pre
//2 3 1 5 4 7 6 in
//3 2 5 7 6 4 1 post
// 1
// 2 4
// 3 5 6
// 7
int n;
scanf("%d", &n);
pre.resize(n);
in.resize(n);
for (int i = 0; i < n; i++) scanf("%d", &pre[i]);
for (int i = 0; i < n; i++) scanf("%d", &in[i]);
postOrder(0, 0, n-1);
return 0;
}
//1 2 3 4 5 6 7 pre
//2 3 1 5 4 7 6 in
//3 2 5 7 6 4 1 post
1053. Path of Equal Weight (30) [树的遍历]
#include "iostream"
#include "algorithm"
#include "vector"
using namespace std;
struct node
{
int w;
vector<int> child;
};
vector<node> v;
vector<int> path;
int target;
bool cmp(int a,int b)
{
return v[a].w > v[b].w;
}
void dfs(int index,int nodeNum,int sum)
{
if(sum>target) return;
if(sum==target)
{
if(v[index].child.size()!=0) return;
for(int i=0; i<nodeNum; i++)
printf("%d%c",v[path[i]].w,i!=nodeNum-1? ' ':'\n');
return;
}
for(int i=0; i<v[index].child.size(); i++)
{
int node = v[index].child[i];
path[nodeNum] = node;
dfs(node,nodeNum+1,sum+v[node].w);
}
}
int main()
{
int n,m;
cin>>n>>m>>target;
v.resize(n);
path.resize(n);
for(int i=0; i<n; i++) cin>>v[i].w;
for(int i=0; i<m; i++)
{
int id,k;
cin>>id>>k;
v[id].child.resize(k);
for(int j=0; j<k; j++) cin>>v[id].child[j];
sort(v[id].child.begin(),v[id].child.end(),cmp);
}
dfs(0,1,v[0].w);
return 0;
}
1079. Total Sales of Supply Chain (25) [DFS,BFS,树的遍历]
#include "iostream"
#include "algorithm"
#include "math.h"
#include "vector"
using namespace std;
struct node
{
vector<int> child;
int amount = 0;
};
vector<node> v;
double sum = 0;
double p,r;
void dfs(int id,int level)
{
// cout<<id<<endl;
if(v[id].child.size()==0)
{
sum += v[id].amount*p*pow(1+r/100,level);
// cout<<sum<<endl;
return ;
}
for(int i=0; i<v[id].child.size(); i++)
dfs(v[id].child[i],level+1);
}
int main()
{
int n;
cin>>n>>p>>r;
v.resize(n);
for(int i=0; i<n; i++)
{
int k,c,amount;
cin>>k;
if(k==0)
{
cin>>amount;
v[i].amount = amount;
}
for(int j=0; j<k; j++){
cin>>c;
v[i].child.push_back(c);
}
}
dfs(0,0);
printf("%.1f",sum);
return 0;
}
1086. Tree Traversals Again (25) [树的遍历]
#include "iostream"
#include "vector"
#include "algorithm"
#include "stack"
using namespace std;
vector<int> in,pre,ans;
void post(int root,int start,int end)
{
if(start>end) return ;
int i = start;
while(i<end&&in[i]!=pre[root]) i++;
post(root+1,start,i-1);//L
post(root+i-start+1,i+1,end);//R
ans.push_back(in[i]);
}
int main()
{
int n;
cin>>n;
stack<int> s;
for(int i=0; i<2*n; i++)
{
string op;
int val;
cin>>op;
if(op[1]=='u')
{
cin>>val;
s.push(val);
pre.push_back(val);
}
else
{
in.push_back(s.top());
s.pop();
}
}
post(0,0,n-1);
cout<<ans[0];
for(int i=1; i<ans.size(); i++)
printf(" %d",ans[i]);
}
1090. Highest Price in Supply Chain (25) [树的遍历]
#include "iostream"
#include "vector"
using namespace std;
struct node
{
vector<int> child;
};
vector<node> v;
int cnt[200010] = {0};
int maxLevel = -1;
void dfs(int id,int level)
{
if(v[id].child.size()==0)
{
if(level>maxLevel)
{
maxLevel = level;
cnt[maxLevel]++;
}
else if(level == maxLevel) cnt[maxLevel]++;
return ;
}
for(int i=0; i<v[id].child.size(); i++) dfs(v[id].child[i],level+1);
}
int main()
{
int n,root;
double p,r;
cin>>n>>p>>r;
v.resize(n+10);
for(int i=0; i<n; i++)
{
int e;
cin>>e;
if(e==-1) root = i;
else v[e].child.push_back(i);
}
dfs(root,0);
double res = p;
for(int i=0; i<maxLevel; i++) res += res*r/100;
printf("%.2f %d",res,cnt[maxLevel]);
return 0;
}
1094. The Largest Generation (25) [BFS,DFS,树的遍历]
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
using namespace std;
struct node
{
vector<int> child;
};
struct rnode
{
int level;
int num;
};
vector<rnode> ans(1010);
vector<node> v;
bool cmp(rnode a,rnode b)
{
return a.num > b.num;
}
void dfs(int id,int level)
{
ans[level].level = level;
ans[level].num++;
node tnode = v[id];
if(tnode.child.size()==0)
{
// printf("lef:%d lvl:%d num:%d\n",id,level,ans[level].num);
return ;
}
for(int i=0; i<tnode.child.size(); i++)
dfs(tnode.child[i],level+1);
}
int main()
{
int n,m;
cin>>n>>m;
v.resize(n+10);
for(int i=0; i<m; i++)
{
int id,k;
cin>>id>>k;
v[id].child.resize(k);
for(int j=0; j<k; j++) cin>>v[id].child[j];
}
dfs(1,1);
sort(ans.begin(),ans.end(),cmp);
cout<<ans[0].num<<" "<<ans[0].level;
return 0;
}
1102. Invert a Binary Tree (25) [树的遍历]
#include "iostream"
#include "string"
#include "algorithm"
#include "vector"
using namespace std;
struct node
{
int id,l,r,level;
};
vector<node> v;
vector<int> in;
bool isRoot[100010] = {false};
bool cmp(node a,node b)
{
if(a.level != b.level) return a.level < b.level;
}
void dfs(int id,int level)
{
v[id].level = level;
// cout<<id<<":"<<v[id].id<<endl;
if(v[id].r!=-1) dfs(v[id].r,2*level);
in.push_back(id);
if(v[id].l!=-1) dfs(v[id].l,2*level+1);
}
int main()
{
int n,root = 0;
cin>>n;
v.resize(n);
for(int i=0; i<n; i++)
{
string a,b;
cin>>a>>b;
int l,r;
if(a=="-") l = -1;
else {
l = stoi(a);
isRoot[l] = true;
}
if(b=="-") r = -1;
else {
r = stoi(b);
isRoot[r] = true;
}
v[i] = {i,l,r,-1};
}
while(isRoot[root]) root++;
dfs(root,1);
sort(v.begin(),v.end(),cmp);
for(int i=0;i<v.size();i++){
if(i!=0) cout<<" ";
cout<<v[i].id;
}
cout<<endl;
for(int i=0;i<in.size();i++){
if(i!=0) cout<<" ";
cout<<in[i];
}
return 0;
}
1106. Lowest Price in Supply Chain (25) [DFS,BFS,树的遍历]
#include "iostream"
#include "algorithm"
#include "vector"
#include "math.h"
using namespace std;
struct node
{
vector<int> child;
};
vector<node> v;
int minLevel = 99999999,minNum = 0;//The max num should use dec.
void dfs(int id,int level)
{
if(v[id].child.size()==0) {
if(level<minLevel){
minNum = 1;
minLevel = level;
}else if(level==minLevel) minNum++;
return ;
}
for(int i=0;i<v[id].child.size();i++){
dfs(v[id].child[i],level+1);
}
}
int main()
{
int n;
double p,r;
cin>>n>>p>>r;
v.resize(n);
for(int i=0;i<n;i++){
int k; cin>>k;
v[i].child.resize(k);
for(int j=0;j<k;j++) cin>>v[i].child[j];
}
dfs(0,0);
printf("%.4f %d",p*pow(1+r/100,minLevel),minNum);
return 0;
}
1115. Counting Nodes in a BST (30) [⼆叉树的遍历,DFS]
#include "iostream"
#include "queue"
#include "vector"
using namespace std;
struct node{
int data,int left=-1,right=-1,level = 0;
};
vector<node> v;
vector<int> ans;
bool vis[100001] = {false};
int numlevel[100100] = {0};
int maxLevel = 0;
void build(int id,int index){
if(v[index].data>v[id].data){
if(v[id].right==-1){
v[id].right = index;
v[index].level = v[id].level+1;
return ;
}
else build(v[id].right,index);
}
else{
if(v[id].left==-1){
v[id].left = index;
v[index].level = v[id].level+1;
return ;
}
else build(v[id].left,index);
}
return ;
}
int main(){
int n;
cin>>n;
v.resize(n);
for(int i=0; i<n; i++) cin>>v[i].data;
for(int i=1; i<v.size(); i++) build(0,i);
maxLevel = 0;
for(int i=0;i<n;i++){
numlevel[v[i].level]++;
if(v[i].level>maxLevel) maxLevel = v[i].level;
}
printf("%d + %d = %d",numlevel[maxLevel],numlevel[maxLevel-1],numlevel[maxLevel-1]+numlevel[maxLevel]);
return 0;
}
1119. Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]
#include <iostream>
#include <vector>
using namespace std;
vector<int> in, pre, post;
bool unique = true;
/*
7
1 2 3 4 6 7 5
2 6 7 4 5 3 1
4
1 2 3 4
2 4 3 1
*/
void getIn(int preLeft, int preRight, int postLeft, int postRight)
{
printf("preL:%d preR:%d postL:%d postR:%d\n",preLeft,preRight,postLeft,postRight);
if(preLeft == preRight)
{
in.push_back(pre[preLeft]);
return;
}
if (pre[preLeft] == post[postRight])//Find the root node
{
int i = preLeft + 1;
while (i <= preRight && pre[i] != post[postRight-1]) i++;//Find the node in pre = post
if (i - preLeft > 1)//i index of pre
getIn(preLeft + 1, i - 1, postLeft, postLeft + (i - preLeft - 1) -1);
else
unique = false;
in.push_back(post[postRight]);
getIn(i, preRight, postLeft + (i - preLeft - 1), postRight - 1);
}
}
int main()
{
int n;
scanf("%d", &n);
pre.resize(n), post.resize(n);
for (int i = 0; i < n; i++)
scanf("%d", &pre[i]);
for (int i = 0; i < n; i++)
scanf("%d", &post[i]);
getIn(0, n-1, 0, n-1);
printf("%s\n%d", unique == true ? "Yes" : "No", in[0]);
for (int i = 1; i < in.size(); i++)
printf(" %d", in[i]);
printf("\n");
return 0;
}
1127. ZigZagging on a Tree (30) [中序后序建树,层序遍历]
#include "iostream"
#include "vector"
#include "algorithm"
#include "math.h"
using namespace std;
struct node
{
int index;
int level;
int data;
};
int n;
vector<int> post,in;
vector<node> ans;
bool cmp(node a,node b)
{
if(a.index != b.index) return a.index < b.index;
}
void pre(int root,int start,int end,int index,int level)
{
if(start>end) return;
int i = start;
while(i<end&&in[i]!=post[root]) i++;
ans.push_back({index,level,in[i]});
pre(root-(end-i+1),start,i-1,2*index,level+1);
pre(root-1,i+1,end,2*index+1,level+1);
}
int main()
{
cin>>n;
post.resize(n);
in.resize(n);
for(int i=0; i<n; i++) cin>>in[i];
for(int i=0; i<n; i++) cin>>post[i];
pre(n-1,0,n-1,1,1);
sort(ans.begin(),ans.end(),cmp);
int curLevel = 1;
vector<int>tmp,rans;
for(int i=0; i<ans.size(); i++)
{
if(ans[i].level==curLevel)
tmp.push_back(ans[i].data);
else
{
if(curLevel%2==0)
for(auto t:tmp) rans.push_back(t);
else
for(int t=tmp.size()-1; t>=0; t--) rans.push_back(tmp[t]);
tmp.clear();
curLevel = ans[i].level;
tmp.push_back(ans[i].data);
}
if(i==ans.size()-1&&!tmp.empty())
{
if(curLevel%2==0)
for(auto t:tmp) rans.push_back(t);
else
for(int t=tmp.size()-1; t>=0; t--) rans.push_back(tmp[t]);
}
}
for(int i=0; i<rans.size(); i++)
{
cout<<rans[i];
if(i!=rans.size()-1) cout<<" ";
}
return 0;
}
1138. Postorder Traversal (25) [树的遍历,前序中序转后序]
#include "iostream"
#include "vector"
#include "map"
using namespace std;
vector<int> pre,in;
vector<int> ans;
void post(int left,int right,int root)
{
if(ans.size()>1) return;
if(left>right) return;
int i = left;
while(in[i]!=pre[root]) i++;
post(left,i-1,root+1);
post(i+1,right,root+1+(i-left));
ans.push_back(in[i]);
}
int main()
{
int n;
cin>>n;
pre.resize(n);
in.resize(n);
for(int i=0;i<n;i++) cin>>pre[i];
for(int i=0;i<n;i++) cin>>in[i];
post(0,n,0);
cout<<ans[0];
return 0;
}
1151. LCA in a Binary Tree (30) [树的遍历,LCA算法]
#include "iostream"
#include "vector"
#include "map"
using namespace std;
vector<int> pre,in;
map<int,int> pos;
void lca(int inl,int inr,int preRoot,int a,int b)
{
if(inl>inr) return ;
int inRoot = pos[pre[preRoot]],aIn = pos[a],bIn = pos[b];
if(aIn<inRoot && bIn<inRoot)
lca(inl,inRoot,preRoot+1,a,b);
else if((aIn<inRoot&&bIn>inRoot)||(aIn>inRoot&&bIn<inRoot))
printf("LCA of %d and %d is %d.\n",a,b,pre[preRoot]);
else if(aIn>inRoot && bIn>inRoot)
lca(inRoot+1,inr,preRoot+1+(inRoot-inl),a,b);
else if(aIn==inRoot)
printf("%d is an ancestor of %d.\n",a,b);
else if(bIn==inRoot)
printf("%d is an ancestor of %d.\n",b,a);
}
int main()
{
int n,m;
cin>>n>>m;
pre.resize(m+1);
in.resize(m+1);
for(int i=1; i<=m; i++)
{
cin>>in[i];
pos[in[i]] = i;
}
for(int i=1; i<=m; i++) cin>>pre[i];
for(int i=0; i<n; i++)
{
int a,b;
cin>>a>>b;
if(pos[a]&&pos[b]) lca(1,m,1,a,b);
else if(pos[a]==0&&pos[b]==0) printf("ERROR: %d and %d are not found.\n",a,b);
else if(!pos[a]) printf("ERROR: %d is not found.\n",a);
else if(!pos[b]) printf("ERROR: %d is not found.\n",b);
}
return 0;
}
1119. Pre- and Post-order Traversals (30) [树的遍历,前序后序转中序]
#include "iostream"
#include "vector"
using namespace std;
vector<int> post, pre, in;
bool unique = true;
void getIn(int preL, int preR, int postL, int postR)
{
if (preL==preR){
in.push_back(pre[preL]);
return;
}
//找到根节点,并据此确定左右子区间的范围
if (pre[preL] == post[postR])
{
int i = preL + 1;
//找到下一个根,它是前序里左右子树分割的关键
while (i <= preR && pre[i] != post[postR - 1]) i++;
//则左子树的范围[preL+1,i-1]
if (i - preL > 1)
getIn(preL + 1, i - 1, postL, postL + i - (preL + 1) - 1);
else
unique = false;
in.push_back(post[postR]);
getIn(i, preR, postL + i - preL - 1, postR - 1);
}
}
int main()
{
int n;
cin >> n;
post.resize(n);
pre.resize(n);
for (size_t i = 0; i < n; i++) cin >> pre[i];
for (size_t i = 0; i < n; i++) cin >> post[i];
getIn(0, n - 1, 0, n - 1);
if (unique) cout << "Yes\n";
else cout << "No\n";
for (size_t i = 0; i < n; i++)
{
if (i != 0) cout << " ";
cout << in[i];
}
cout << endl;
system("pause");
return 0;
}
二叉查找树(BST/AVL) 相关题
1123. Is It a Complete AVL Tree (30) [AVL树]
#include "iostream"
#include "vector"
#include "queue"
using namespace std;
struct node
{
int val;
struct node *left, *right;
};
node* leftRotate(node *tree)
{
node *tmp = tree->right;
tree->right = tmp->left;
tmp->left = tree;
return tmp;
}
node* rightRotate(node *tree)
{
node *tmp = tree->left;
tree->left = tmp->right;
tmp->right = tree;
return tmp;
}
node* leftRightRotate(node *tree)
{
tree->left = leftRotate(tree->left);
return rightRotate(tree);
}
node* rightLeftRotate(node *tree)
{
tree->right = rightRotate(tree->right);
return leftRotate(tree);
}
int getHeight(node* tree)
{
if (tree == NULL) return 0;
int l = getHeight(tree->left);
int r = getHeight(tree->right);
return max(l, r) + 1;
}
node* insert(node *tree,int val)
{
if (tree == NULL){
tree = new node();
tree->val = val;
tree->left = tree->right = NULL;
}
if (val < tree->val){
tree->left = insert(tree->left,val);
int l = getHeight(tree->left);
int r = getHeight(tree->right);
if (l - r>1){
if (val < tree->left->val){//LL
tree = rightRotate(tree);
}
else{
tree = leftRightRotate(tree);
}
}
}
else if (val > tree->val){
tree->right = insert(tree->right, val);
int l = getHeight(tree->left);
int r = getHeight(tree->right);
if (r - l > 1){
if (val > tree->right->val){//RR
tree = leftRotate(tree);
}
else{
tree = rightLeftRotate(tree);
}
}
}
return tree;
}
bool isComplete = true;
int after = 0;
vector<int> levelTrav(node *tree)
{
queue<node*> q;
vector<int> v;
q.push(tree);
while (!q.empty())
{
node *tmp = q.front();
v.push_back(tmp->val);
q.pop();
if (tmp->left != NULL) {
if (after) isComplete = false;
q.push(tmp->left);
}
else {
after = 1;
}
if (tmp->right != NULL) {
if (after) isComplete = false;
q.push(tmp->right);
}
else
{
after = 1;
}
}
return v;
}
int main()
{
int n, e;
cin >> n;
node *tree = NULL;
for (size_t i = 0; i < n; i++)
{
cin >> e;
tree = insert(tree, e);
}
vector<int> ans = levelTrav(tree);
for (size_t i = 0; i < ans.size(); i++)
{
if (i != 0) cout << " ";
cout << ans[i];
}
printf("\n%s", isComplete ? "YES": "NO");
system("pause");
return 0;
}
并查集 相关题
1107. Social Clusters (30) [并查集]
#include "iostream"
#include "vector"
#include "algorithm"
#include "stdio.h"
using namespace std;
const int MAXV = 1001;
int hobby[MAXV] = { 0 };
int father[MAXV] = { 0 };
int isRoot[MAXV] = { 0 };
bool cmp(int a, int b){
return a > b;
}
int findFather(int x)
{
int a = x;
if (father[x] == x) {
while (a!=father[a])
{
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
else return findFather(father[x]);
}
void Union(int a,int b)
{
int fa = findFather(a);
int fb = findFather(b);
if (fa != fb) father[fa] = fb;
}
int main()
{
int n;
cin >> n;
for (size_t i = 1; i <= n; i++)
{
father[i] = i;
}
for (size_t i = 1; i <= n; i++)
{
int m;
scanf_s("%d:", &m);
for (size_t j = 1; j <= m; j++)
{
int e;
cin >> e;
if (hobby[e] == 0)
hobby[e] = i;
Union(i, findFather(hobby[e]));
}
}
for (size_t i = 1; i <= n; i++) isRoot[findFather(i)]++;
vector<int> ans;
for (size_t i = 1; i <= n; i++)
{
if (isRoot[i] != 0) ans.push_back(isRoot[i]);
}
sort(ans.begin(), ans.end(), cmp);
cout << ans.size() << endl;
for (size_t i = 0; i < ans.size(); i++)
{
if (i != 0) cout << " ";
cout << ans[i];
}
system("pause");
return 0;
}
1118. Birds in Forest (25) [并查集]
#include "iostream"
#include "vector"
#include "set"
using namespace std;
const int MAXV = 10010;
bool vis[MAXV];
int num;
int father[MAXV];
struct node
{
vector<int> child;
};
vector<node> v(MAXV);
void dfs(int s)
{
vis[s] = true;
for (size_t i = 0; i <v[s].child.size(); i++)
{
int id = v[s].child[i];
if (!vis[id]){
dfs(id);
father[id] = s;
}
}
}
int findFather(int s)
{
if (father[s] == s) return s;
else
{
father[s] = findFather(father[s]);
return father[s];
}
}
int main()
{
int n;
cin >> n;
set<int> s;
fill(vis, vis + MAXV, false);
for (size_t i = 0; i < n; i++)
{
int t;
cin >> t;
int e, laste = 0;
for (size_t j = 0; j < t; j++)
{
cin >> e;
if (laste == 0) laste = e;
v[e].child.push_back(laste);
v[laste].child.push_back(e);
s.insert(e);
laste = e;
}
}
num = s.size();
int blocks = 0;
for (size_t i = 1; i <= num; i++)
{
father[i] = i;
}
for (size_t i = 1; i <= num; i++)
{
if (!vis[i]) {
blocks++;
dfs(i);
}
}
cout << blocks << " " << num << endl;
int q;
cin >> q;
for (size_t i = 0; i < q; i++)
{
int a, b;
cin >> a >> b;
int fa = findFather(a);
int fb = findFather(b);
if (fa == fb) printf("Yes\n");
else printf("No\n");
}
system("pause");
return 0;
}
堆 相关题
图 相关题
图的遍历 相关题
1013. Battle Over Cities (25) [图的遍历,统计连通分量的个数,DFS]
#include "iostream"
#include "vector"
#include "string.h"
#define INF 65535
#define MAXN 2000
using namespace std;
int graph[MAXN][MAXN] = {INF};
bool vis[MAXN] = {false};
int n,m,k;
void dfs(int i)
{
vis[i] = true;
for(int j=1; j<=n; j++)
{
if(graph[i][j]&&!vis[j])
{
dfs(j);
}
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1; i<=n; i++)
{
graph[i][i] = 0;
}
for(int i=1; i<=m; i++)
{
int gi,gj;
cin>>gi>>gj;
graph[gi][gj] = 1;
}
for(int i=1; i<=k; i++)
{
int q;
cin>>q;
memset(vis,false,sizeof(vis));
int block = 0;
vis[q] = true;
for(int j=1; j<=n; j++)
{
if(!vis[j])
{
block++;
dfs(j);
}
}
cout<<block-1;
if(i!=k) cout<<endl;
}
return 0;
}
1021. Deepest Root (25) [图的遍历,DFS,计算连通分量的个数]
#include "iostream"
#include "vector"
using namespace std;
const int MAXV = 1000;
const int INF = 10000000;
int n,m,s,dest;
int G[MAXV][MAXV];
int w[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];
vector<vector<int> > pre(MAXV);
vector<int> tempPath,path;
void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
fill(vis,vis+MAXV,false);
d[s] = 0;
for(int i=0;i<n;i++){
int u = -1,MIN = INF;
for(int v=0;v<n;v++){
if(!vis[v]&&d[v]<MIN){
u = v;
MIN = d[v];
}
}
if(u==-1) return;
// cout<<"u:"<<u<<endl;
vis[u] = true;
for(int v=0;v<n;v++){
if(!vis[v]&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
// cout<<v<<"IPush:"<<u<<endl;
}else if(d[u]+G[u][v]==d[v]){
// cout<<v<<"IIPush:"<<u<<endl;
pre[v].push_back(u);
}
}
}
}
}
int minDis = INF,minCost = INF;
void dfs(int v)
{
if(v==s)
{
int cost = 0,dis = 0;
tempPath.push_back(v);
for(int i=tempPath.size()-1;i>0;i--){
int id = tempPath[i];
int nextId = tempPath[i-1];
dis += G[id][nextId];
cost += w[id][nextId];
}
// cout<<dis<<endl;
if(dis<minDis){
minDis = dis;
minCost = cost;
path = tempPath;
}else if(dis==minDis&&cost<minCost){
minCost = cost;
path = tempPath;
}
tempPath.pop_back();
return ;
}
tempPath.push_back(v);
for(int i=0;i<pre[v].size();i++){
dfs(pre[v][i]);
}
tempPath.pop_back();
}
int main()
{
fill(G[0],G[0]+MAXV*MAXV,INF);
fill(w[0],w[0]+MAXV*MAXV,INF);
cin>>n>>m>>s>>dest;
for(int i=0;i<m;i++){
int u,v,e,c;
cin>>u>>v>>e>>c;
G[u][v] = G[v][u] = e;
w[u][v] = w[v][u] = c;
}
Dijkstra(s);
dfs(dest);
for(int i=path.size()-1;i>=0;i--) cout<<path[i]<<" ";
cout<<minDis<<" ";
cout<<minCost<<endl;
return 0;
}
1034. Head of a Gang (30) [图的遍历,DFS]
#include "iostream"
#include "vector"
#include "map"
#define MAXN 100010
using namespace std;
map<int,string> idName;
map<string,int> nameId,head;
vector<int> callLen(MAXN);
int maxId = 0,maxCall = 0;
map<string,int> ans;
int graph[2000][2000];
bool vis[MAXN] = {false};
int cnt = 1;
void dfs(int i,int &k,int &peoNum)
{
for(int j=1; j<cnt; j++)
{
if(graph[i][j]>0)
{
callLen[i] += graph[i][j];
callLen[j] += graph[i][j];
if(callLen[i]>maxCall)
{
maxId = i;
maxCall = callLen[i];
}
else if(callLen[j]>maxCall)
{
maxId = j;
maxCall = callLen[j];
}
k += graph[i][j];
if(!vis[j]) peoNum++;
vis[j] = true;
graph[i][j] = -1;
graph[j][i] = -1;
dfs(j,k,peoNum);
}
}
}
int main()
{
int n,k;
cin>>n>>k;
for(int i=0; i<n; i++)
{
string a,b;
int len;
cin>>a>>b>>len;
if(nameId[a]==0)
{
nameId[a] = cnt;
idName[cnt++] = a;
}
if(nameId[b]==0)
{
nameId[b] = cnt;
idName[cnt++] = b;
}
graph[nameId[a]][nameId[b]] += len;
graph[nameId[b]][nameId[a]] += len;
}
int blocks = 0;
// cout<<cnt<<endl;
for(int i=1; i<cnt; i++)
{
int time = 0;
int peoNum = 1;
maxCall = 0;
maxId = 0;
if(!vis[i])
{
vis[i] = true;
dfs(i,time,peoNum);
if(time>k&&peoNum>2)
{
blocks++;
ans[idName[maxId]] = peoNum;
}
}
}
printf("%d\n",blocks);
for(auto it=ans.begin();it!=ans.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
1076. Forwards on Weibo (30) [图的遍历,BFS]
#include "iostream"
#include "vector"
#include "queue"
#include "string.h"
using namespace std;
int G[1010][1010];
int n,level,num;
bool vis[1010] = {false};
struct node
{
int id;
int depth;
};
void bfs(int i)
{
queue<node> q;
q.push({i,0});
vis[i] = true;
while(!q.empty())
{
node tmp = q.front();
// cout<<tmp.id<<endl;
num++;
q.pop();
for(int j=1;j<=n;j++){
// cout<<tmp.id<<":"<<j<<"->"<<G[tmp.id][j]<<endl;
if(!vis[j]&&G[tmp.id][j]&&tmp.depth<level){
vis[j] = true;
q.push({j,tmp.depth+1});
}
}
}
}
int main()
{
cin>>n>>level;
for(int i=1;i<=n;i++){
int t;
cin>>t;
for(int j=0;j<t;j++){
int a;
cin>>a;
G[a][i] = 1;
}
}
int q;
cin>>q;
for(int i=0;i<q;i++){
int a;
num = 0;
memset(vis,false,sizeof(vis));
cin>>a;
bfs(a);
cout<<num-1<<endl;
}
return 0;
}
Dijkstra 相关题
1003. Emergency (25) [Dijkstra算法
#include "iostream"
#include "vector"
using namespace std;
const int INF = 1000000;
const int MAXN = 1000;
bool vis[MAXN] = {false};
int d[MAXN] = {INF};
int w[MAXN] = {0};
int num[MAXN] = {0};
int weight[MAXN] = {0};
int G[MAXN][MAXN];
/*
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
*/
void Dijkstra(int s,int ed,int n)
{
fill(d,d+MAXN,INF);
d[s] = 0;
// weight[s] = res[s];
//Find the closet one
for(int i=0; i<n; i++)
{
int u = -1,MIN = INF;
for(int j=0; j<n; j++)
{
if(vis[j]==false&&d[j]<MIN)
{
u = j;
MIN = d[j];
}
}
if(u==-1) return;
vis[u] = true;
for(int v=0; v<n; v++)
{
if(!vis[v]&&G[u][v]<INF)
{
if(d[u]+G[u][v]<d[v]){
d[v] = d[u]+G[u][v];
num[v] = num[u];
w[v] = w[u] + weight[v];
}else if(d[v]==d[u]+G[u][v]){
num[v] = num[u]+num[v];
if(w[u]+weight[v]>w[v]){
w[v] = w[u] + weight[v];
}
}
}
}
}
}
int main()
{
int n,e,st,ed;
cin>>n>>e>>st>>ed;
fill(G[0],G[0]+MAXN*MAXN,INF);
for(int i=0; i<n; i++) cin>>weight[i];
for(int i=0; i<e; i++)
{
int a,b,len;
cin>>a>>b>>len;
G[a][b] = G[b][a] = len;
}
int cnt = 1,numRes = 0;
num[st] = 1;
w[st] = weight[st];
Dijkstra(st,ed,n);
cout<<num[ed]<<" "<<w[ed]<<endl;
return 0;
}
//Summary:
/*
1.路径累积考虑用一个num数组来维护
2.原始的weight尽量不要动,而要用另一个辅助数组去存储中间值
3.矩阵初始化用fill,不要用memset,{}这种初始化方法不是很靠谱,尽可能用fill
4.Dijkstra就是一个固定模板,捻熟于心。
*/
1030. Travel Plan (30) [Dijkstra算法 + DFS,最短路径,边权]
#include "iostream"
#include "vector"
using namespace std;
const int MAXV = 1000;
const int INF = 10000000;
int n,m,s,dest;
int G[MAXV][MAXV];
int w[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];
vector<vector<int> > pre(MAXV);
vector<int> tempPath,path;
void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
fill(vis,vis+MAXV,false);
d[s] = 0;
for(int i=0;i<n;i++){
int u = -1,MIN = INF;
for(int v=0;v<n;v++){
if(!vis[v]&&d[v]<MIN){
u = v;
MIN = d[v];
}
}
if(u==-1) return;
// cout<<"u:"<<u<<endl;
vis[u] = true;
for(int v=0;v<n;v++){
if(!vis[v]&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
// cout<<v<<"IPush:"<<u<<endl;
}else if(d[u]+G[u][v]==d[v]){
// cout<<v<<"IIPush:"<<u<<endl;
pre[v].push_back(u);
}
}
}
}
}
int minDis = INF,minCost = INF;
void dfs(int v)
{
if(v==s)
{
int cost = 0,dis = 0;
tempPath.push_back(v);
for(int i=tempPath.size()-1;i>0;i--){
int id = tempPath[i];
int nextId = tempPath[i-1];
dis += G[id][nextId];
cost += w[id][nextId];
}
// cout<<dis<<endl;
if(dis<minDis){
minDis = dis;
minCost = cost;
path = tempPath;
}else if(dis==minDis&&cost<minCost){
minCost = cost;
path = tempPath;
}
tempPath.pop_back();
return ;
}
tempPath.push_back(v);
for(int i=0;i<pre[v].size();i++){
dfs(pre[v][i]);
}
tempPath.pop_back();
}
int main()
{
fill(G[0],G[0]+MAXV*MAXV,INF);
fill(w[0],w[0]+MAXV*MAXV,INF);
cin>>n>>m>>s>>dest;
for(int i=0;i<m;i++){
int u,v,e,c;
cin>>u>>v>>e>>c;
G[u][v] = G[v][u] = e;
w[u][v] = w[v][u] = c;
}
Dijkstra(s);
dfs(dest);
for(int i=path.size()-1;i>=0;i--) cout<<path[i]<<" ";
cout<<minDis<<" ";
cout<<minCost<<endl;
return 0;
}
1072. Gas Station (30) [Dijkstra算法]
#include "iostream"
#include "vector"
#include "cstring"
#include "string"
using namespace std;
const int MAXV = 2000;
const int INF = 100000000;
int nh,ns,nr,ds;
int G[MAXV][MAXV];
bool vis[MAXV] = {false};
int d[MAXV];
void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
fill(vis,vis+MAXV,false);
d[s] = 0;
for(int i=1;i<=nh+ns;i++){
int u = -1,MIN = INF;
for(int v=1;v<=nh+ns;v++){
if(!vis[v]&&d[v]<MIN){
u = v;
MIN = d[v];
}
}
if(u==-1) return;
vis[u] = true;
for(int v=1;v<=nh+ns;v++){
if(!vis[v]&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v] = d[u] + G[u][v];
}
}
}
}
}
int main()
{
fill(G[0],G[0]+MAXV*MAXV,INF);
cin>>nh>>ns>>nr>>ds;
for(int i=1;i<=nr;i++){
string sa,sb;
int a,b,len;
cin>>sa>>sb>>len;
if(sa[0]=='G'){
a = nh+stoi(sa.substr(1,sa.size()-1));
}else{
a = stoi(sa);
}
if(sb[0]=='G'){
b = nh+stoi(sb.substr(1,sb.size()-1));
}else{
b = stoi(sb);
}
G[a][b] = G[b][a] = len;
}
int Gid = -1;
double minAver = INF,maxDis = -1;
for(int i=nh+1;i<=nh+ns;i++){
Dijkstra(i);
int dis = INF;
double aver = 0;
for(int j=1;j<=nh;j++){
if(d[j]>ds) {
dis = -1;
break;
}
else {
if(d[j]<dis){
dis = d[j];
}
aver += 1.0*d[j]/nh;
}
}
if(dis==-1) continue;
if(dis>maxDis){
maxDis = dis;
minAver = aver;
Gid = i;
}else if(dis==maxDis&&aver<minAver){
minAver = aver;
Gid = i;
}else if(dis==maxDis&&aver==minAver){
Gid = min(i,Gid);
}
}
if(Gid!=-1) printf("G%d\n%.1f %.1f\n",Gid-nh,maxDis,minAver);
else printf("No Solution\n");
return 0;
}
1087. All Roads Lead to Rome (30) [Dijkstra算法 + DFS,最短路径]
#include "iostream"
#include "vector"
#include "map"
using namespace std;
const int MAXV = 1000;
const int INF = 100000000;
map<string,int> idCity;
map<int,string> nameCity;
int nc,nr;
string st;
int w[MAXV],d[MAXV];
bool vis[MAXV] = {false};
int G[MAXV][MAXV];
int num[MAXV];
vector<vector<int> > pre(MAXV);
vector<int> path,tempPath;
void Dijkstra(int s)
{
fill(vis,vis+MAXV,false);
fill(d,d+MAXV,INF);
d[s] = 0;
for(int i=0; i<nc; i++)
{
int u = -1,MIN = INF;
for(int v=0; v<nc; v++)
{
if(!vis[v]&&d[v]<MIN)
{
u = v;
MIN = d[v];
}
}
if(u==-1) return;
vis[u] = true;
for(int v=0; v<nc; v++)
{
if(!vis[v]&&G[u][v]!=INF)
{
if(d[u]+G[u][v]<d[v])
{
d[v] = d[u]+G[u][v];
num[v] = num[u];
pre[v].clear();
pre[v].push_back(u);
// if(v==1) cout<<"1ROM!"<<num[v]<<"u:"<<u<<"->"<<num[u]<<endl;
}
else if(d[u]+G[u][v]==d[v])
{
num[v]+=num[u];
pre[v].push_back(u);
// if(v==1) cout<<"2ROM!"<<num[v]<<"u:"<<u<<"->"<<num[u]<<endl;
}
}
}
}
}
int maxHap = -1;
int averHap = 0;
void dfs(int v)
{
if(v==idCity[st])
{
int hap = 0;
int aver = 0;
tempPath.push_back(v);
for(int i=tempPath.size()-1; i>=0; i--)
{
int id = tempPath[i];
hap += w[id];
}
if(tempPath.size()==1) aver = 0;
else aver = hap/(tempPath.size()-1);
if(hap>maxHap)
{
maxHap = hap;
averHap = aver;
path = tempPath;
}
else if(hap==maxHap&&aver>averHap)
{
averHap = aver;
path = tempPath;
}
tempPath.pop_back();
}
tempPath.push_back(v);
for(int i=0; i<pre[v].size(); i++)
{
dfs(pre[v][i]);
}
tempPath.pop_back();
}
int main()
{
fill(G[0],G[0]+MAXV*MAXV,INF);
num[0] = 1;
cin>>nc>>nr>>st;
nameCity[0] = st;
idCity[st] = 0;
for(int i=1; i<nc; i++)
{
string name;
int hap;
cin>>name>>hap;
nameCity[i] = name;
idCity[name] = i;
w[i] = hap;
}
for(int i=0; i<nr; i++)
{
string ca,cb;
int cost;
cin>>ca>>cb>>cost;
int u = idCity[ca],v = idCity[cb];
G[u][v] = G[v][u] = cost;
}
int romId = idCity["ROM"];
if(st=="ROM") printf("1 0 %d %d\nROM",w[romId],w[romId]);
else
{
Dijkstra(idCity[st]);
dfs(romId);
printf("%d %d %d %d\n",num[romId],d[romId],maxHap,averHap);
for(int i=path.size()-1; i>=0; i--)
{
cout<<nameCity[path[i]];
if(i!=0) cout<<"->";
}
}
return 0;
}
1111. Online Map (30) [Dijkstra算法 + DFS]
#include "iostream"
#include "vector"
using namespace std;
const int MAXV = 550;
const int INF = 100000000;
int Graph[MAXV][MAXV],Gtime[MAXV][MAXV];
int d[MAXV];
int nv,nr,st,ed;
bool vis[MAXV];
vector<vector<int> > pre(MAXV);
vector<int> path,tempPath;
void Dijkstra(int s,int G[][MAXV])
{
pre.clear();
fill(d,d+MAXV,INF);
fill(vis,vis+MAXV,false);
d[s] = 0;
for(int i=0; i<nv; i++)
{
int u = -1,MIN = INF;
for(int v=0; v<nv; v++)
{
if(!vis[v]&&d[v]<MIN)
{
u = v;
MIN = d[v];
}
}
if(u==-1) return;
vis[u] = true;
for(int v=0; v<nv; v++)
{
if(!vis[v]&&G[u][v]!=INF&&Graph[u][v]!=INF)
{
if(d[u]+G[u][v]<d[v])
{
d[v] = d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u]+G[u][v]==d[v])
{
pre[v].push_back(u);
}
}
}
}
}
int minDis = INF,minTime = INF,minPathLen = INF;
void dfs(int v,int mode)
{
if(v==st)
{
int curDis = 0,timeUse = 0,pathLen;
tempPath.push_back(v);
pathLen = tempPath.size();
for(int i=tempPath.size()-1; i>0; i--)
{
int id = tempPath[i];
int nextId = tempPath[i-1];
curDis += Graph[id][nextId];
timeUse += Gtime[id][nextId];
}
if(mode==0)
{
if(curDis<minDis)
{
minDis = curDis;
minTime = timeUse;
path = tempPath;
}
else if(curDis==minDis&&timeUse<minTime)
{
minTime = timeUse;
path = tempPath;
}
}
else
{
if(pathLen<minPathLen)
{
minTime = timeUse;
minPathLen = pathLen;
path = tempPath;
}
}
tempPath.pop_back();
}
tempPath.push_back(v);
for(int i=0; i<pre[v].size(); i++)
{
dfs(pre[v][i],mode);
}
tempPath.pop_back();
}
int main()
{
vector<int> shortPath;
fill(Graph[0],Graph[0]+MAXV*MAXV,INF);
fill(Gtime[0],Gtime[0]+MAXV*MAXV,INF);
cin>>nv>>nr;
for(int i=0; i<nr; i++)
{
int u,v,flag,len,time;
cin>>u>>v>>flag>>len>>time;
if(!flag)
{
Graph[u][v] = Graph[v][u] = len;
Gtime[u][v] = Gtime[v][u] = time;
}
else
{
Graph[u][v] = len;
Gtime[u][v] = time;
}
}
cin>>st>>ed;
Dijkstra(st,Graph);
dfs(ed,0);//cacu shortest path
shortPath = path;
printf("Distance = %d",minDis);
path.clear();
tempPath.clear();
Dijkstra(st,Gtime);
dfs(ed,1);//cacu fastest path
if(shortPath==path)
{
printf("; ");
}
else
{
printf(": ");
for(int i=shortPath.size()-1; i>=0; i--)
{
cout<<shortPath[i];
if(i!=0) cout<<" -> ";
}
cout<<endl;
}
printf("Time = %d: ",minTime);
for(int i=path.size()-1; i>=0; i--)
{
cout<<path[i];
if(i!=0) cout<<" -> ";
}
return 0;
}
水题
1136. A Delayed Palindrome (20) [⽔题]
#include "algorithm"
#include "iostream"
using namespace std;
string rev(string s)
{
reverse(s.begin(),s.end());
return s;
}
string add(string a,string b)
{
int carry = 0;
string s = a;
for(int i=a.length()-1; i>=0; --i)
{
s[i] = (a[i]-'0' + b[i]-'0'+carry)%10 + '0';
carry = (a[i]-'0' + b[i]-'0' + carry)/10;
}
if(carry>0) s = "1"+s;
return s;
}
int main()
{
string num;
cin>>num;
if(num==rev(num))
{
cout<<num<<" is a palindromic number."<<endl;
return 0;
}
int n = 10;
while(n--)
{
string s = add(num,rev(num));
cout<<num<<" + "<<rev(num)<<" = "<<s<<endl;
if(s == rev(s))
{
cout<<s<<" is a palindromic number."<<endl;
return 0;
}
num = s;
}
cout<<"Not found in 10 iterations."<<endl;
return 0;
}
1143. Lowest Common Ancestor (30) [⽔题]
#include "iostream"
#include "vector"
#include "map"
using namespace std;
vector<int> v;
map<int,int> pos;
int main()
{
int n,m;
cin>>n>>m;
v.resize(m+1);
for(int i=1; i<=m; i++)
{
cin>>v[i];
pos[v[i]] = i;
}
for(int i=1; i<=n; i++)
{
int a,b;
cin>>a>>b;
if(pos[a]==0&&pos[b]==0) printf("ERROR: %d and %d are not found.\n",a,b);
else if(pos[a]==0) printf("ERROR: %d is not found.\n",a);
else if(pos[b]==0) printf("ERROR: %d is not found.\n",b);
else
{
for(int j=1; j<=m; j++)
{
if(v[j]>=min(a,b)&&v[j]<=max(a,b))
{
if(v[j]==a) printf("%d is an ancestor of %d.\n",a,b);
else if(v[j]==b) printf("%d is an ancestor of %d.\n",b,a);
else printf("LCA of %d and %d is %d.\n",a,b,v[j]);
break;
}
}
}
}
return 0;
}
1139. First Contact (30) [⽔题]
#include "iostream"
#include "vector"
#include "algorithm"
#include "map"
#include "string"
using namespace std;
struct node
{
int gender;
vector<int> frd;
};
vector<node> v(10000);
int G[10000][10000] = { 0 };
bool cmp(int a, int b) {
return a < b;
}
int main()
{
int n, m, a, b, gender;
string sa, sb;
cin >> n >> m;
for (size_t i = 0; i < m; i++)
{
cin >> sa >> sb;
if (sa == "0000") sa = "1388";
else if (sa == "-0000") sa = "-1388";
if (sb == "0000") sb = "1388";
else if (sb == "-0000") sb = "-1388";
a = stoi(sa);
b = stoi(sb);
v[abs(a)].frd.push_back(b);
v[abs(b)].frd.push_back(a);
G[abs(a)][abs(b)] = G[abs(b)][abs(a)] = 1;
}
int q;
cin >> q;
while (q--)
{
vector<int> frdA, frdB;
int fid = 0;
cin >> a >> b;
for (size_t i = 0; i < v[abs(a)].frd.size(); i++)
{
fid = v[abs(a)].frd[i];
if (a*fid>0 && abs(b) != abs(fid)){//same gendle
frdA.push_back(abs(fid));
}
}
for (size_t i = 0; i < v[abs(b)].frd.size(); i++)
{
fid = v[abs(b)].frd[i];
if (b*fid>0 && abs(a) != abs(fid)){//same gendle
frdB.push_back(abs(fid));
}
}
sort(frdA.begin(), frdA.end(),cmp);
sort(frdB.begin(), frdB.end(),cmp);
vector<pair<int, int> > ans;
for (size_t i = 0; i < frdA.size(); i++)
{
int idA = frdA[i];
for (size_t j = 0; j < frdB.size(); j++)
{
int idB = frdB[j];
if (G[idA][idB]){
if (idA == 1388) idA = 0;
if (idB == 1388) idB = 0;
ans.push_back({ idA, idB });
}
}
}
cout << ans.size() << endl;
for (auto i : ans) printf("%04d %04d\n", i.first, i.second);
}
system("pause");
return 0;
}
1148. Werewolf – Simple Version (20) [⽔题]
#include "iostream"
#include "vector"
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> sta(n + 1);
for (size_t i = 1; i <= n; i++) cin >> sta[i];
for (size_t i = 1; i <= n; i++)
{
for (size_t j = i+1; j <=n ; j++)
{
vector<int> a(n + 1, 1);
a[i] = a[j] = -1;
int lia = 0, lib = 0;
int cnt = 0;
for (size_t k = 1; k <= n; k++)
{
if (a[abs(sta[k])] * sta[k] < 0){
cnt++;
if (cnt == 1) lia = k;
else if (cnt == 2) lib = k;
}
}
if (cnt == 2 && a[lia] + a[lib] == 0){
printf("%d %d\n", i, j);
system("pause");
return 0;
}
}
}
printf("No Solution\n");
system("pause");
return 0;
}
近五场考试
基础数据结构模板
线性表
树
图
基础算法
哈希映射、并查集、最短路径、拓扑排序、关键路径、贪心、深度优先搜索、广度优先搜索、回溯剪枝
PAT其余题目浏览
堆
1155 Heap Paths (30 分)
输入:给定堆的序列,然后问是不是堆?如果是的话是大堆还是小堆?并输出从根到每个叶子的值
分析:堆首先是一个完全二叉树,因此可根据下标来判断
判断叶子节点:index2以及index2+1均大于n
1147 Heaps (30 分)
输入:给定堆的序列,问是不是堆,和1155类似。
根据前两个数来判断是大堆还是小堆,之后访问所有节点的孩子节点,若有一个与之前的大小堆逻辑不符,则不是堆
是堆后,输出结果
图
1150 Travelling Salesman Problem (25 分)
输入:给定图的边集以及路线,问给定路线是否符合条件
分析:TS环要求所有点需访问到,因此可用set来判断是否合规
因输出的情况多样,考虑用flag标记输出的先后逻辑(如 是simple环得先是环)
有先后逻辑的:用flag处理
拓扑排序
1146 Topological Order (25 分)
输入:给定有向图的边集,判断所给序列是否是topo序列
分析:topo边集,一律考虑用邻接表,并且构建入度数组来维护
判断topo序列:依次入队,若入度不为0则不是topo排序,每次入队之后,其所指向的点的入度减一
哈希
1145 Hashing - Average Search Time (25 分)
输入:给定表的大小,然后通过H计算idx,采用平方探查法解决hash冲突,若表大小不为奇数,则调整表的大小至大于给定数的最小素数
输出:平均搜索时间
分析:
-
大于i的最小素数
while(!isprime(tsize)) tsize++;
-
平方探查法怎么写(同时也是flag的妙用)
for (int i = 0; i < n; i++) { scanf("%d", &a); int flag = 0; for (int j = 0; j < tsize; j++) { int pos = (a + j * j) % tsize;//对每个数据都用平方探查法插入 if (v[pos] == 0) { v[pos] = a; flag = 1;//找到了就置1 break; } } } if (!flag) printf("%d cannot be inserted.\n", a);//找不到就fail
-
AST怎么算?
查找结束的标志:pos 处的元素命中(成功)或无数据(失败),则查找结束
int ans = 0; for (int i = 0; i < m; i++) { scanf_s("%d", &a); for (int j = 0; j <= tsize; j++) { ans++; int pos = (a + j * j) % tsize; if (v[pos] == a || v[pos] == 0) break;//查找结束的标志 } }
二叉搜索树
1135 Is It A Red-Black Tree (30 分)
输入:给定红黑树的前序序列,建树,并判断是不是红黑树
问题:
-
如何建树?
-
红黑树的条件?