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

推荐订阅源

大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
量子位
A
Arctic Wolf
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
V
Vulnerabilities – Threatpost
博客园 - Franky
C
Cyber Attacks, Cyber Crime and Cyber Security
The Cloudflare Blog
Last Week in AI
Last Week in AI
The Hacker News
The Hacker News
I
Intezer
J
Java Code Geeks
P
Privacy International News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Secure Thoughts
Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
S
Securelist
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
Jina AI
Jina AI
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
T
Tenable Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy & Cybersecurity Law Blog
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 【当耐特】
T
Threat Research - Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
K
Kaspersky official blog
H
Help Net Security
宝玉的分享
宝玉的分享
罗磊的独立博客
Webroot Blog
Webroot Blog
月光博客
月光博客
B
Blog RSS Feed
Recorded Future
Recorded Future

山岳库博

自建虚拟局域网实现文明六稳定联机 追光者 快手面经(二〇二四年五月九日) 一文搞懂伪代码 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;
}