PAT2021秋季备考总结

PAT2021秋季备考总结

考纲原文

在达到乙级要求的基础上,还要求:

  1. 具有充分的英文阅读理解能力;
  2. 理解并掌握基础数据结构,包括:线性表
  3. 理解并熟练编程实现经典高级算法,包括哈希映射并查集最短路径拓扑排序关键路径贪心深度优先搜索广度优先搜索回溯剪枝等;
  4. 具备较强的问题抽象和建模能力,能实现对复杂实际问题的模拟求解。

刷题总结

模拟题

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冲突,若表大小不为奇数,则调整表的大小至大于给定数的最小素数

输出:平均搜索时间

分析:

  1. 大于i的最小素数

    while(!isprime(tsize)) tsize++;
    
  2. 平方探查法怎么写(同时也是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
    
  3. 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 分)

输入:给定红黑树的前序序列,建树,并判断是不是红黑树

问题:

  1. 如何建树?

    
    
  2. 红黑树的条件?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值