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);
}