惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
美团技术团队
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
L
LangChain Blog
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
腾讯CDC
Recent Announcements
Recent Announcements
The Register - Security
The Register - Security
有赞技术团队
有赞技术团队
Blog — PlanetScale
Blog — PlanetScale
博客园 - Franky
博客园 - 司徒正美
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
C
Check Point Blog
小众软件
小众软件
V
Visual Studio Blog
V
V2EX
F
Full Disclosure
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
罗磊的独立博客
人人都是产品经理
人人都是产品经理
量子位
Apple Machine Learning Research
Apple Machine Learning Research
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
博客园_首页
Y
Y Combinator Blog
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
Recorded Future
Recorded Future
G
Google Developers Blog
Vercel News
Vercel News
大猫的无限游戏
大猫的无限游戏
Microsoft Azure Blog
Microsoft Azure Blog
U
Unit 42
爱范儿
爱范儿
Jina AI
Jina AI

山岳库博

自建虚拟局域网实现文明六稳定联机 追光者 快手面经(二〇二四年五月九日) 一文搞懂伪代码 Swpp Backends 官方文档 Butterfly 友链魔改教程 在 MavenCentral 上发布你的项目 控制台游戏引擎开发文档 MI——高级合成表模块 人狼羊菜过河详细题解 蓝桥杯 2023 训练四 Java 全解 蓝桥杯 2023 训练三 Java 全解 蓝桥杯 2023 训练二 Java 全解 全自动博客部署方案 小白也能用的 SW 构建插件 MI—电力系统工作原理 MI文档——自动化GUI绘制 给博客添加追番页面 网站加载速度优化方案总结 给博客添加自定义的通知悬浮窗
2023 级新生周赛第二周题解
空梦 · 2023-11-05 · via 山岳库博
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

typedef long long LL;
typedef struct Mark Mark;
// 用链表实现一个栈
struct Mark {
Mark* prev; // 上一个节点
char* type; // 节点名称
};

bool readln(char* str);
bool invoke();
void pushItem(char* name, int start, int end);
char* popItem();
int indexOfAny(const char* src, int start, int end, char* items);
char* indexOfInRange(char* src, int length, const char* that);
bool strEquals(char* src, int length, const char* that);
bool isSelfClosing(char* src, int start, int end);

char distId[1010] = {'i', 'd', '=', '"'}; // 目标 ID
char input[1001]; // 单行输入
char content[3001]; // 结果
bool hit = false; // 判断是否找到了 id 为指定字符串的标签
Mark* linkedList = NULL;

int main() {
readln(distId + 4);
int idLength = (int) strlen(distId);
distId[idLength] = '"';
distId[idLength + 1] = '\0';
if (!invoke()) printf("duo lao a cjmm");
else if (!hit) printf("duo lao a cjjj");
else {
bool isNotBlank = false;
for (int i = 0; content[i] != '\0'; ++i) {
switch (content[i]) {
case ' ': case '\t': case '\n':
break;
default:
isNotBlank = true;
goto skipFor;
}
}
skipFor:
if (!isNotBlank) printf("QAQ");
else {
int start = 0;
for (; content[start] != '\0'; ++start) {
if (content[start] != '\n') break;
}
printf("%s", content + start);
}
}
return 0;
}

bool invoke() {
bool skip = false;
char* contentStartFlag = NULL;
int contentStartIndex;
int contentLength = 0;
while (readln(input)) {
int length = (int) strlen(input);
int i = 0;
if (skip) {
LL endIndex = (LL) (strstr(input, "-->") - input);
if (endIndex < 0) continue;
i = (int) (endIndex + 3);
}
while (i != length) {
LL tmp = (LL) (strchr(input + i, '<') - input);
if (tmp < 0) break;
int startIndex = (int) tmp;
// 判断是否是注释
if (startIndex + 3 < length && input[startIndex + 1] == '!' && input[startIndex + 2] == '-' && input[startIndex + 3] == '-') {
LL endIndex = (LL) (strstr(input + i, "-->") - input);
if (endIndex < 0) { // endIndex < 0 表明注释不在一行内结束
skip = true;
break;
}
i = (int) (endIndex + 3); // 如果在一行内结束就跳过注释中的内容
continue;
}
int endIndex = (int) (strchr(input + startIndex + 1, '>') - input);
if (input[startIndex + 1] == '/') { // 如果是结束标记
char* oldName = popItem();
if (oldName == NULL) return false; // 没有开始标记,结构错误
bool isEquals = strEquals(input + startIndex + 2, endIndex - startIndex - 2, oldName);
bool isContent = oldName == contentStartFlag;
free(oldName);
if (!isEquals) return false; // 开始标记和结束标记不对应,结构错误
if (isContent) {
contentStartFlag = NULL;
int len = startIndex - contentStartIndex;
memcpy(content + contentLength, input + contentStartIndex, sizeof(char) * len);
contentLength += len;
}
} else { // 如果是开始标记
int nameEndIndex = indexOfAny(input, startIndex + 1, endIndex + 1, " >");
bool selfClosing = input[endIndex - 1] == '/' || isSelfClosing(input, startIndex + 1, nameEndIndex);
if (!selfClosing) pushItem(input, startIndex + 1, nameEndIndex);
char* idIndex = indexOfInRange(input + startIndex + 1, endIndex - startIndex - 1, distId);
if (idIndex != NULL) { // 如果找到了对应的 ID
hit = true;
if (!selfClosing) {
contentStartFlag = linkedList->type;
contentStartIndex = endIndex + 1;
}
}
}
i = endIndex + 1;
}
if (contentStartFlag != NULL) {
int len = length - contentStartIndex;
memcpy(content + contentLength, input + contentStartIndex, sizeof(char) * len);
contentLength += len;
contentStartIndex = 0;
content[contentLength++] = '\n';
}
}
content[contentLength] = '\0';
return !skip && linkedList == NULL;
}

/** 读取一行数据 */
bool readln(char* str) {
memset(str, 0, sizeof(char) * 1000);
char *flag = gets(str);
return flag != NULL;
}

// 在字符串的指定范围内查找 items 中字符最早出现的那一个的下标
int indexOfAny(const char* src, int start, int end, char* items) {
for (int i = start; i != end; ++i) {
char value = src[i];
char* dist = strchr(items, value);
if (dist != NULL) return i;
}
return -1;
}

// 推送一个节点到栈中
void pushItem(char* name, int start, int end) {
Mark* newItem = malloc(sizeof(Mark));
newItem->prev = linkedList;
int length = end - start;
newItem->type = malloc(sizeof(char) * (length + 1));
memcpy(newItem->type, name + start, sizeof(char) * length);
newItem->type[length] = '\0';
linkedList = newItem;
}

// 弹出栈顶元素
char* popItem() {
if (linkedList == NULL) return NULL;
Mark* oldItem = linkedList;
char* oldType = oldItem->type;
linkedList = oldItem->prev;
free(oldItem);
return oldType;
}

// 在指定范围内比较字符串是否相等
bool strEquals(char* src, int length, const char* that) {
char tmp = src[length];
src[length] = '\0';
bool result = strcmp(src, that) == 0;
src[length] = tmp;
return result;
}

// 在指定范围内查找字符串
char* indexOfInRange(char* src, int length, const char* that) {
char tmp = src[length];
src[length] = '\0';
char* result = strstr(src, that);
src[length] = tmp;
return result;
}

const char SELF_LIST[][11] = {"br", "hr", "img", "input", "link", "meta", "area"};

// 判断是否是自闭合标签
bool isSelfClosing(char* src, int start, int end) {
src = src + start;
int length = end - start;
for (int i = 0; i != 7; ++i) {
if (strEquals(src, length, SELF_LIST[i]))
return true;
}
return false;
}