L1-011 A-B(20 分)提问
本题要求你计算A-B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A-B。
输入格式:
输入在2行中先后给出字符串A和B。两字符串的长度都不超过10^4^,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出A-B的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
思路:一个比较直接的方法就是直接两重循环,依次遍历即可,经测试,能AC。。
代码实现:
#include<stdio.h>
#include<string.h>
int main()
{
char s[10005],ss[10005];
int i, j, ls, lss, flag;
gets(s);
gets(ss);
ls = strlen(s);
lss = strlen(ss);
for(i = 0; i < ls; i++)
{
flag = 1;
for(j = 0; j < lss; j++)
{
if(s[i]==ss[j])
{
flag = 0;
break;
}
}
if(flag) printf("%c",s[i]);
}
}
2018/7/25 09:40:43 | 答案正确 | 20 | L1-011 | C (gcc) | 64 ms | 2016082102 |
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 2 ms | 384KB |
1 | 答案正确 | 41 ms | 256KB |
2 | 答案正确 | 2 ms | 256KB |
3 | 答案正确 | 64 ms | 256KB |
但是可以看到最后一个样例到了64ms,那怎么优化呢?
那就说到了标记数组:
大致思路:把S2字符串的每个字符都标记一下,因为是ASCII码,所以数组不用太大,肯定会有重复的字符出现。然后遍历S1,看这个字符是否被标记过即可。
代码实现:
#include<stdio.h>
#include<string.h>
int flag[200];
int main()
{
char s[10005],ss[10005];
int i, ls, lss;
gets(s);
gets(ss);
ls = strlen(s);
lss = strlen(ss);
for(i = 0; i < lss; i++)
flag[ss[i]] = 1;
for(i = 0; i < ls; i++)
{
if(!flag[s[i]])
printf("%c", s[i]);
}
}
经测试,结果如下:
2018/7/25 09:33:10 | 答案正确 | 20 | L1-011 | C (gcc) | 4 ms | 2016082102 |
测试点 | 结果 | 耗时 | 内存 |
---|---|---|---|
0 | 答案正确 | 2 ms | 276KB |
1 | 答案正确 | 3 ms | 276KB |
2 | 答案正确 | 3 ms | 384KB |
3 | 答案正确 | 4 ms | 344KB |
这就是标记数组的一个应用,很多算法的实现都用到了标记数组,比如回溯法,Dijkstra最短路,这也是一种重要的剪枝方法。好了,我就通过这么一道水题,讲一讲标记数组的应用,希望对大家有帮助吧!