2022年省赛预选赛(数据结构与STL)题解

问题 B: 吃在工大
请添加图片描述
解题思路:
拓补排序,,要求按照字典序最大的那一组,因此直接用优先级队列进行处理即可。

#include<bits/stdc++.h>
using namespace std;
vector < int > v[1000];
int d[1000];
int main() {
    ios :: sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        memset(d, 0, sizeof(d));
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            v[i].clear();
        }
        while (m--) {
            int a, b;
            cin >> a >> b;
            v[a].push_back(b);
            d[b]++;
        }
        priority_queue < int, vector < int > , less < int >> q;
        for (int i = 1; i <= n; i++) {
            if (d[i] == 0) {
                q.push(i);
            }
        }
        int num = 0;
        int s[n + 10];
        memset(s, 0, sizeof(s));
        while (q.empty() != 1) {
            int x = q.top();
            q.pop();
            s[num++] = x;
            for (int i = 0; i < v[x].size(); i++) {
                int u = v[x][i];
                d[u]--;
                if (d[u] == 0) {
                    q.push(u);
                }
            }
        }
        if (num != n) {
            cout <<- 1 << endl;
        }
        else {
            for (int i = 0; i < num - 1; i++) {
                cout << s[i] << " ";
            }
            cout << s[num - 1] << endl;
        }
    }
    return 0;
}

C.Cute Tree
Given the pseudo-code of a function Build−Tree(A,id,L,R):
在这里插入图片描述
where A is given in input, id is the number of node, L ,R is the left position and the right position of A

Require the number of nodes created by Build−Tree(A,root,1,n).
输入
The first line contains an integer T (1≤T≤5) representing the number of test cases.

For each test case, the first contain one integer n(1≤n≤2∗105).

The second line contain n integers Ai(1≤ Ai ≤109).
输出
For each test output one line, the number of nodes created by Build−Tree(A,root,1,n).

解题思路:
直接按照图片所给的伪代码敲即可,输入的A数组其实没啥大用,考虑到输入规模比较大,建议使用scanf和printf进行输入输出.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int sum;
int n;
int a[maxn];
int bulidtree(int l,int r){
	sum++;
	if(l == r){
		return sum;
	}
	else if(r - l == 1){
		int mid = floor((l + r) >> 1);
		bulidtree(l,l);
		bulidtree(r,r);
	}
	else {
		int b = l + ceil((r - l) / 3);
		int c = floor((b + r) >> 1);
		bulidtree(l,b);
		bulidtree(b+1,c);
		bulidtree(c+1,r); 
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		sum = 0;
		for(int i=0;i<n;i++)cin >> a[i];
		cout << bulidtree(1,n) << "\n";
	}
	
	return 0;
}

D.单身晚会
请添加图片描述
解题思路:
floyd最短路径算法,用佛罗里德算法求出各个点到其他点的最短路径,然后求最小值即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
const int INF = INT_MAX;
int dis[maxn][maxn];
int a[maxn];
int n, p, c;
void floyd() {
    for(int k = 1; k <= p; k++) {
        for(int i = 1; i <= p; i++) {
            for (int j = 1; j <= p; j++) {
                if(dis[i][k] != INF && dis[k][j] != INF && dis[i][k] + dis[k][j] < dis[i][j])
                    dis[i][j] = dis[i][k] + dis[k][j];
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while(t--) {
        cin >> n >> p >> c;
        fill(dis[0], dis[0] + maxn * maxn, INF);
        for(int i = 0; i <= p; i++) dis[i][i] = 0;
        for(int i = 1; i <= n; i++) cin >> a[i];
        for(int i = 0; i < c; i++) {
            int u, v, w;
            cin >> u >> v >> w;
            dis[u][v] = dis[v][u] = min(dis[u][v], w);
        }
        floyd();
        // for(int i = 1; i <= p; i++) {
        //     for(int j = 1; j <= p; j++) {
        //         cout << dis[i][j] << " ";
        //     }
        //     cout << endl;
        // }
        int ans = INF;
        for(int i = 1; i <= p; i++) {
            int sum = 0;
            bool flag = true;
            for(int j = 1; j <= n; j++) {
                if(dis[i][j] != INF)sum += dis[i][a[j]];
                else {
                    flag = false;
                    break;
                }
            }
            if(flag) ans = min(ans, sum);
        }
        cout << ans << "\n";
    }
    return 0;
}

E.营救(save)

请添加图片描述

解题思路:
广度优先搜索板子题。

E.java

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class node{
    int x;
    int y;
    int step;
    node(int x,int y,int step){
        this.x = x;
        this.y = y;
        this.step = step;
    }
}
public class Main{
    static int n,o,p;
    static int [][]a = new int[1200][1200];
    static boolean [][]inq = new boolean[1200][1200];
    static int []X = new int[]{1,-1,0,0};
    static int []Y = new int[]{0,0,1,-1};
    static node start;
    static boolean judge(int x,int y){
        if(x<=0 || y<=0 || x>n || y>n)return false;
        if(inq[x][y] || a[x][y] == 1)return false;
        return true;
    }
    static void bfs(){
        //int ans = 0;
        Queue<node> q = new LinkedList< node >();
        q.offer(start);
        while(!q.isEmpty()){
            node top = q.poll();
            //System.out.println(top.x+" "+top.y+" "+top.step);
            //System.out.println(o + " " +p);
            if(top.x == o && top.y == p){
                System.out.println(top.step);
                //ans = top.step;
                return ;
            }
            for(int i=0;i<4;i++){
                int newx = top.x + X[i];
                int newy = top.y + Y[i];
                if(judge(newx,newy)){
                    q.offer(new node(newx,newy,top.step+1));
                    inq[newx][newy] = true;
                }
            }
        }
        //return ans;
    }
    public static void main(String[] args) {
        n = cin.nextInt();
        for(int i=1;i<=n;i++){
            String s = cin.next();
            for(int j=1;j<=n;j++){
                a[i][j] = (s.charAt(j-1) - '0');
                inq[i][j] = false;
            }
        }
        start = new node(cin.nextInt(),cin.nextInt(),0);
        //end.x = cin.nextInt();
        //end.y = cin.nextInt();
        o = cin.nextInt();
        p = cin.nextInt();
//        end.step = 0;
//        System.out.println(start.x+" "+start.y+" "+start.step);
        //System.out.println(bfs());
        bfs();
        cin.close();
    }
    static Scanner cin = new Scanner(System.in);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值