天梯赛 2.10

本文介绍了四个编程问题,涉及并查集的使用、最小堆的插入和查找、二叉树的构建与调整,以及列车调度的优化算法。通过这些示例展示了数据结构和算法在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

L2-010 排座位

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#define N 110
int p[N * 2];
int s[N][N][1];
int vis[N];
int findth(int x) {
    if (x == p[x]) return x;  
    return p[x] = findth(p[x]);  
}
unionn(int x, int y) {  
    int xx = findth(x);  
    int yy = findth(y);  
    if (xx != yy) {
        p[yy] = xx;
    }
}
int main() {
    int n, m, k;
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < N * 2; i++) {  
        p[i] = i;  
    }  
    memset(s, 0, sizeof(s));  
    memset(vis, 0, sizeof(vis));  
  
    // 读取并处理m个操作  
    for (int i = 0; i < m; i++) {  
        int a, b, c;  
        scanf("%d %d %d", &a, &b, &c);  
        if (c == 1) {  
            unionn(a, b);  
        } else {  
            s[a][b][0] = 1;  
            s[b][a][0] = 1;  
        }  
    }  
  
    // 处理k个查询  
    for (int i = 0; i < k; i++) {  
        int a, b;  
        scanf("%d %d", &a, &b);  
        if (findth(a) == findth(b) && !(s[a][b][0] || s[b][a][0])) {  
            puts("No problem");  
        } else {  
            if (s[a][b][0] || s[b][a][0]) {  
                // 清空vis数组  
                memset(vis, 0, sizeof(vis));  
  
                // 标记与a相连的所有节点  
                for (int j = 1; j <= n; j++) {  
                    if (a != j && findth(a) == findth(j)) {  
                        vis[j] = 1;  
                    }  
                }  
  
                // 检查是否存在与b相连且被标记的节点  
                int flag = 0;  
                for (int j = 1; j <= n; j++) {  
                    if (vis[j] && findth(b) == findth(j)) {  
                        flag = 1;  
                        break;  
                    }  
                }  
  
                if (flag) {  
                    puts("OK but...");  
                } else {  
                    puts("No way");  
                }  
            } else {  
                puts("OK");  
            }  
        }  
    }  
  
    return 0;  
}

L2-011 玩转二叉树

#include <stdio.h>  
#include <stdlib.h>
typedef struct node {
    int data;  
    struct node* left;
    struct node* right;
} node;
node* build(int in[], int pre[], int n) {  
    if (!n)  
        return NULL;  
    node* t = (node*)malloc(sizeof(node));  
    t->data = pre[0];  
    t->left = t->right = NULL;  
    int i;  
    for (i = 0; i < n; i++) {  
        if (in[i] == pre[0])  
            break;  
    }  
    t->left = build(in, pre + 1, i);  
    t->right = build(in + i + 1, pre + i + 1, n - i - 1);  
    return t;  
}  
  
node* change(node* t) {  
    if (t) {  
        if (t->left != NULL || t->right != NULL) {  
            node* m = t->left;  
            t->left = t->right;  
            t->right = m;  
        }  
        change(t->left);  
        change(t->right);  
    }  
    return t;  
}  
  
void cengci(node* t, int n) {  
    node* q[1000];  
    int ll = 0, rr = 0, len = 0;  
    if (t) {  
        q[rr++] = t;  
        while (ll != rr) {  
            node* p = q[ll++];  
            printf("%d", p->data);  
            len++;  
            if (len != n) {  
                printf(" ");  
            } else {  
                printf("\n");  
                len = 0; // 重置len为0,以便下一层的输出  
            }  
            if (p->left != NULL) {  
                q[rr++] = p->left;  
            }  
            if (p->right != NULL) {  
                q[rr++] = p->right;  
            }  
        }  
    }  
}  
  
int main() {  
    node* t;  
    int i, n;  
    scanf("%d", &n);  
    int in[1000], pre[1000];  
    for (i = 0; i < n; i++) {  
        scanf("%d", &in[i]);  
    }  
    for (i = 0; i < n; i++) {  
        scanf("%d", &pre[i]);  
    }  
    t = build(in, pre, n);  
    t = change(t);  
    cengci(t, n);  
    // 释放内存(这在实际使用中非常重要,以避免内存泄漏)  
    return 0;  
}

L2-012 关于堆的判断

#include <stdio.h>
#include <stdlib.h>
const int MINDATA = -999999999;  
int N, M, x;
typedef struct HNode *Heap;  
struct HNode {  
    int *data;  
    int size;  
    int capacity;  
};  
  
Heap createHeap(int maxsize) {  
    // 创建容量为maxsize的空的最小堆  
    Heap H = (Heap)malloc(sizeof(struct HNode));  
    H->data = (int *)malloc((maxsize + 1) * sizeof(int));  
    H->size = 0;  
    H->capacity = maxsize;  
    H->data[0] = MINDATA; // 定义“哨兵”为小于堆中所有可能元素的值  
    return H;  
}  
  
int isFull(Heap H) {  
    return (H->size == H->capacity);  
}  
  
int insert(Heap H, int X) {  
    // 最小堆的插入  
    int i;  
    if (isFull(H)) {  
        return 0;  
    }  
    i = ++H->size; // i指向插入后堆中的最后一个元素的位置  
    for (; H->data[i / 2] > X; i /= 2)  
        H->data[i] = H->data[i / 2];
    H->data[i] = X; // 将x插入  
    return 1;  
}  
  
int find(Heap H, int x) {  
    for (int i = 1; i <= H->size; i++) {  
        if (H->data[i] == x) {  
            return H->data[i / 2];  
        }  
    }  
    return -1; // 如果没有找到x,返回-1  
}  
  
int main() {  
    scanf("%d%d", &N, &M);  
    Heap H = createHeap(N);  
    for (int i = 0; i < N; i++) {  
        scanf("%d", &x);  
        insert(H, x);  
    }  
    char s1[10], s2[10], s3[10];  
    for (int i = 0; i < M; i++) {  
        int x, y;  
        scanf("%d%s", &x, s1);  
        if (strcmp(s1, "and") == 0) {
            scanf("%d%s%s", &y, s2, s3);  
            if (find(H, x) == find(H, y))  
                printf("T\n");  
            else  
                printf("F\n");  
            continue;  
        }  
        scanf("%s", s1);  
        if (strcmp(s1, "a") == 0) {
            scanf("%s%s%d", s2, s3, &y);  
            if (find(H, x) == y)  
                printf("T\n");  
            else  
                printf("F\n");  
            continue;  
        }  
        scanf("%s", s1);  
        if (strcmp(s1, "root") == 0) {
            if (find(H, x) == MINDATA)
                printf("T\n");  
            else  
                printf("F\n");  
            continue;  
        }  
        scanf("%s%d", s1, &y);
        if (find(H, y) == x)  
            printf("T\n");  
        else  
            printf("F\n");  
    }
    free(H->data);
    free(H);
    return 0;
}

 L2-013 红色警报

#include <stdio.h>
#include <stdlib.h>
#define MAX 505
int n, m, k;  
int pre[MAX]; // 并查集数组  
int vis[MAX]; // 判断是否已经被攻占  
typedef struct {  
    int first;  
    int second;  
} Pair;  
Pair P[5005]; // 保存初始的连通信息  
  
// 初始化并查集  
void init() {  
    for (int i = 0; i < n; i++) {  
        pre[i] = i;  
    }  
}  
  
// 并查集的查找  
int Find(int x) {  
    if (pre[x] != x) return Find(pre[x]);  
    return x;  
}  
  
// 并查集的合并  
void merge2(int x, int y) {  
    int fx = Find(x);  
    int fy = Find(y);  
    if (fx != fy) {  
        pre[fx] = fy;  
    }  
}  
  
int main() {  
    // 初始化vis数组  
    for (int i = 0; i < MAX; i++) {  
        vis[i] = 0;  
    }  
    scanf("%d %d", &n, &m);  
    init();  
    for (int i = 0; i < m; i++) {  
        scanf("%d %d", &P[i].first, &P[i].second);  
        merge2(P[i].first, P[i].second);  
    }  
  
    int cnt = 0;  
    // 计算初始连通的区域数  
    for (int i = 0; i < n; i++) {  
        if (pre[i] == i) {  
            cnt++;  
        }  
    }
    // 读取k和每个被攻占的城市  
    scanf("%d", &k);  
    for (int t = 0; t < k; t++) {  
        int u;  
        scanf("%d", &u);  
        // 标记城市为已攻占
        vis[u] = 1;
        init();
        for (int i = 0; i < m; i++) {  
            int x = P[i].first, y = P[i].second;  
            if (!vis[x] && !vis[y]) {  
                merge2(x, y);  
            }  
        }  
  
        int cur = 0;
        for (int i = 0; i < n; i++) {  
            if (!vis[i] && pre[i] == i) {  
                cur++;  
            }
        }
        if (cur + 1 == cnt || cur == cnt) {  
            printf("City %d is lost.\n", u);  
        } else {  
            printf("Red Alert: City %d is lost!\n", u);  
        }
        cnt = cur;  
    }
    if (k == n) {  
        printf("Game Over.\n");  
    }
    return 0;  
}

 L2-014 列车调度

#include<stdio.h>
int a[1000000];
int main()
{
	int n;
	scanf("%d",&n);
	int i,m,j,top=0;
	for(i=0;i<n;i++){
		scanf("%d",&m);
		if(top==0||a[top-1]<m){  //当top==0时,开辟轨道,当输入的列车序号比最上的轨道列车序号还大时,开辟轨道
			a[top++]=m;
		}else
		{ 
			int high=top-1,low=0,mid;
			while(low<=high)
			{
				mid=(low+high)/2;
				if(a[mid]>m)
				{
					high=mid-1;
				}else
				{
					low=mid+1;
				}
			}//a[mid]=m;
			a[low]=m;
		}
	}printf("%d",top);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值