2019年三峡大学新生编程赛
7.破解密码
(1)题目内容:
作为出题组中一名热爱运动的探险家,小Y喜欢上山下乡去寻找宝藏,这一次他选择去三峡大学求索溪边的翠屏山上进行探索,经历重重困难,小Y终于找到了宝箱。小Y十分的开心。
然而这个宝箱需要密码才能打开。
但是破解密码怎么会难倒我们的探险家小Y呢?所以他仔细的观察了宝箱。
在宝箱前的一个石碑上刻着一长串的字符,显然密码就隐藏在里面。经验丰富的他迅速地明白了破解密码的方式,但是这段字符实在太长了,所以小Y就找来了你来帮助他解决。
密码就是这串字符中含有不重复字符的最长子串,因为密码就只有一个,所以这样的子串只有一个。
(串中任意个连续的字符组成的子序列称为该串的子串)
(2)输入描述
输入一个字符串s(1 <= s的长度 <= 1e6)
(3)输出描述
输出一行,表示该字符串中含有不重复字符的最长子串
(4)输入样例
absadfasddfas
(5)输出样例
bsadf
(6)限制条件
JAVA 运行时间 2000ms 运行内存 3000kb
C++ 运行时间 1000ms 运行内存 3000kb
(7)程序代码
#include <stdio.h>
#include <string.h>
struct {
char date[1000050];
int head;
int tail;
} queue, itemp;
int main() {
gets(queue.date);
int num = strlen(queue.date);
queue.head = 0;
queue.tail = num;
int len = 0;
int i;
while (1) {
int book[1000] = {0};
for (i = queue.head; i < queue.tail; i++) {
book[queue.date[i]]++;
if (book[queue.date[i]] > 1 || i == num - 1) {
queue.tail = i;
if (len < queue.tail - queue.head) {
len = queue.tail - queue.head;
itemp.head = queue.head;
itemp.tail = queue.tail;
}
queue.head++;
queue.tail = num;
break;
}
}
if (i == num - 1) break;
}
for (i = itemp.head; i < itemp.tail; i++) printf("%c", queue.date[i]);
return 0;
}
(8)解题思路以及题目分析
本题根据题意,是求不含重复字符的最大字串,如果暴力硬解很有可能会导致超时,于是可以选择上述代码的方式,从第一项开始往后判断,如果没有出现重复字符就继续往后面存,一旦出现了重复的情况就再往后进行判断,比较字符串的长度,选取最大长度输出,具体实现见上述代码。
(9)题目总结
此题难度适中,主要在于如何找到最长字符串的思想以及如何判断是否存在重复字符的最简单方法,上述代码中使用对应字符的ASCII码为下标的数组记录显然是最简单的方法。