Fork me on GitHub

HDU2087-剪花布条

继续跟邝斌飞刷KMP

HDU2087

 

关于可见字符,大概从33到126共94个可见的字符。

这题挺简单,直接匹配的时候子串不判断是否到末尾了就行,到末尾就计数cnt+1然后再从头来直到主串到末尾

 

妈的这题挺狡猾啊,输入的时候发现布条和饰条之间不一定只有一个空格,可能有多个,比如第二组数据

 

写完WA了

复制代码
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 char a[1001];
 6 char b[1001];
 7 int ne[1001];
 8 int main()
 9 {
10     string str;
11     while(getline(cin,str) && str!="#"){
12         int len=str.length();
13         int len_a=0;
14         int len_b=0;
15         for(int i=0;i<len;i++){
16             if(str[i]==' ')
17                 break;
18             else{
19                 a[i]=str[i];
20                 len_a++;
21             }
22         }
23         for(int i=len_a+1;i<len;i++){
24             if(str[i]==' ')//妈的布条后还有多余空格
25                 continue;
26             b[len_b]=str[i];
27             len_b++;
28 //            cout<<str[i]<<endl;
29         }
30 //        for(int i=0;i<len_a;i++)
31 //            cout<<a[i];
32 //        cout<<endl;
33 //        for(int i=0;i<len_b;i++)
34 //            cout<<b[i];
35 //        cout<<endl;
36 //输入数据结束,md这段挺简单,但写起来再读就不是很容易,过一个月我都看不懂自己的输入数据部分
37 
38         int p=0;
39         if(len_a<len_b){
40             cout<<0<<endl;
41             p=1;
42         }
43         if(p==1)
44             continue;//简单处理下特殊情况,布条比饰条短还匹配个JB
45 
46 //        处理next数组
47         int k=-1;
48         int j=0;
49         ne[0]=-1;
50         while(j<len_b-1){
51             if(k==-1 || b[j]==b[k]){
52                 j++;
53                 k++;
54                 if(b[j]==b[k])
55                     ne[j]=ne[k];
56                 else
57                     ne[j]=k;
58             }
59             else
60                 k=ne[k];
61         }
62 
63 //        开始匹配
64         int i=0;
65         j=0;
66         int ans=0;
67         while(i<len_a){
68             if(j==len_b){
69 //                cout<<"#"<<i<<" "<<j<<endl;
70                 ans++;
71                 j=0;
72             }
73             if(j==-1 || a[i]==b[j]){
74 //                cout<<"@"<<i<<" "<<j<<endl;
75                 i++;
76                 j++;
77             }
78             else
79                 j=ne[j];
80         }
81 
82         //发现最后一个如果可以匹配,但也出循循环了,所以ans还得再加1
83         if(i==len_a && j==len_b){
84             ans++;
85             cout<<ans<<endl;//写完发现不用最开始那个布条<饰条的特判也行
86         }
87         if(i==len_a && j!=len_b)
88             cout<<0<<endl;
89 //        cout<<endl;
90     }
91 }
View Code
复制代码

测试发现下面这组数据输出0(中间我用的是tab制表符)

afsa    a

而下面这组数据能正确输出2

asfa a

加了句判断还不行

复制代码
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 char a[1001];
 6 char b[1001];
 7 int ne[1001];
 8 int main()
 9 {
10     string str;
11     while(getline(cin,str) && str!="#"){
12         int len=str.length();
13         int len_a=0;
14         int len_b=0;
15         for(int i=0;i<len;i++){
16 //            if(str[i]==' ')
17             if(str[i]<33 || str[i]>126)
18                 break;
19 
20             else{
21                 a[i]=str[i];
22                 len_a++;
23             }
24         }
25         for(int i=len_a+1;i<len;i++){
26 //            if(str[i]==' ')//妈的布条后还有多余空格
27 //妈的除了空格还有好多不可见的字符
28             if(str[i]<33 || str[i]>126)
29                 continue;
30             b[len_b]=str[i];
31             len_b++;
32 //            cout<<str[i]<<endl;
33         }
34 //        for(int i=0;i<len_a;i++)
35 //            cout<<a[i];
36 //        cout<<endl;
37 //        for(int i=0;i<len_b;i++)
38 //            cout<<b[i];
39 //        cout<<endl;
40 //输入数据结束,md这段挺简单,但写起来再读就不是很容易,过一个月我都看不懂自己的输入数据部分
41 
42         int p=0;
43         if(len_a<len_b){
44             cout<<0<<endl;
45             p=1;
46         }
47         if(p==1)
48             continue;//简单处理下特殊情况,布条比饰条短还匹配个JB
49 
50 //        处理next数组
51         int k=-1;
52         int j=0;
53         ne[0]=-1;
54         while(j<len_b-1){
55             if(k==-1 || b[j]==b[k]){
56                 j++;
57                 k++;
58                 if(b[j]==b[k])
59                     ne[j]=ne[k];
60                 else
61                     ne[j]=k;
62             }
63             else
64                 k=ne[k];
65         }
66 
67 //        开始匹配
68         int i=0;
69         j=0;
70         int ans=0;
71         while(i<len_a){
72             if(j==len_b){
73 //                cout<<"#"<<i<<" "<<j<<endl;
74                 ans++;
75                 j=0;
76             }
77             if(j==-1 || a[i]==b[j]){
78 //                cout<<"@"<<i<<" "<<j<<endl;
79                 i++;
80                 j++;
81             }
82             else
83                 j=ne[j];
84         }
85 
86         //发现最后一个如果可以匹配,但也出循循环了,所以ans还得再加1
87         if(i==len_a && j==len_b){
88             ans++;
89             cout<<ans<<endl;//写完发现不用最开始那个布条<饰条的特判也行
90         }
91         if(i==len_a && j!=len_b)
92             cout<<0<<endl;
93 //        cout<<endl;
94     }
95 }
View Code
复制代码

想到如果输入一个布条然后回车是不是也应该等待输入

可是输入“a”,回车,输出了2,是因为len_b是0,直接误以为匹配上ans+1了

回头看题说 “输入中含有一些数据,分别是成对出现的花布条和小饰条”,并没说都在一行,那代码就要重写,找一个可以吃回车的,知道出现可见的两组字符才算输入完一组

 

思考个问题:

这样只能用不吃回车和空格的cin,string,cin很慢啊,scanf还无法读string。之前那些涉及到读取string的只能用cin,那些AC了是否数据量不够大?这个数据量大不也一样会TLE吗???先搁置 (更新,不纠结了,确实如此,以用cin就大概率会TLE著称的POJ也是)

 

投机取巧写法WA了

复制代码
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<iostream>
  4 using namespace std;
  5 char a[1001];
  6 char b[1001];
  7 int ne[1001];
  8 int main()
  9 {
 10     string str;
 11     while(getline(cin,str) && str!="#"){
 12         int len=str.length();
 13         int len_a=0;
 14         int len_b=0;
 15         for(int i=0;i<len;i++){
 16             if(str[i]<33 || str[i]>126)
 17                 break;
 18 
 19             else{
 20                 a[i]=str[i];
 21                 len_a++;
 22             }
 23         }
 24         for(int i=len_a+1;i<len;i++){
 25             if(str[i]<33 || str[i]>126)
 26                 continue;
 27             b[len_b]=str[i];
 28             len_b++;
 29         }
 30 
 31 
 32 
 33 if(len_b==0){//投机取巧看能不能A
 34     cin>>str;
 35     for(int i=0;i<str.length();i++){
 36         b[len_b]=str[i];
 37         len_b++;
 38     }
 39 }
 40 //cout<<len_a<<" "<<len_b<<endl;
 41 
 42         int p=0;
 43         if(len_a<len_b){
 44             cout<<0<<endl;
 45             p=1;
 46         }
 47         if(p==1)
 48             continue;
 49 
 50 //        处理next数组
 51         int k=-1;
 52         int j=0;
 53         ne[0]=-1;
 54         while(j<len_b-1){
 55             if(k==-1 || b[j]==b[k]){
 56                 j++;
 57                 k++;
 58                 if(b[j]==b[k])
 59                     ne[j]=ne[k];
 60                 else
 61                     ne[j]=k;
 62             }
 63             else
 64                 k=ne[k];
 65         }
 66 
 67 //        for(int i=0;i<len_a;i++)
 68 //            cout<<"!"<<a[i];
 69 ////        cout<<endl;
 70 ////        for(int i=0;i<len_b;i++)
 71 ////            cout<<"@"<<b[i];
 72 ////        cout<<endl;
 73 //        for(int i=0;i<len_a;i++)
 74 //            cout<<"$"<<ne[i];
 75 //        cout<<endl;
 76 
 77 //cout<<"&"<<len_b<<endl;
 78 //        开始匹配
 79         int i=0;
 80         j=0;
 81         int ans=0;
 82         while(i<len_a){
 83             if(j==len_b){
 84 //                cout<<"#"<<i<<" "<<j<<endl;
 85                 ans++;
 86                 j=0;
 87             }
 88             if(j==-1 || a[i]==b[j]){
 89 //                cout<<"@"<<i<<" "<<j<<endl;
 90                 i++;
 91                 j++;
 92             }
 93             else
 94                 j=ne[j];
 95         }
 96 
 97         //发现最后一个如果可以匹配,但也出循循环了,所以ans还得再加1
 98         if(i==len_a && j==len_b){
 99             ans++;
100             cout<<ans<<endl;//写完发现不用最开始那个布条<饰条的特判也行
101         }
102         if(i==len_a && j!=len_b)
103             cout<<0<<endl;
104 //        cout<<endl;
105     }
106 }
View Code
复制代码

发现输入asd a输出0,发现输出ans逻辑有问题,改下再提交

试了下感觉没错了但输入“3回车3回车”输出1,再输入“3 3回车”,输出两个0,应该是getline导致缓冲区有回车,md投机取巧反而耽误时间了

重新写下,

一种写法是两个都是string类型的,输入一个ASC符合的char字符就拼接一个,但太耗时,舍弃。

一种是直接cin两个string类型的,完美略掉不可见的字符,但cin这玩意不想用,太慢。

针对输入想说的是,上一个题指定了是整型,如果是字符类型,那上个题的scanf就完犊子了。回顾下上个博客的知识点,cin不吃空格回车,scanf吃空格回车

直接scanf一个字符一个字符的,判断符合要求就读取吧,

但想了下上一个题声明的是数组,一个一个字符的scanf读,挨个赋值给数组可以AC,用cin读就TLE,如果是string类型读完了再拼接更TLE,但因为有空格,所以不可以之直接cin string。

但这道题输入形式是两个串的中间没空格,那我如果用比较耗时的cin一次直接读取整个的string,会不会比,虽然读取速度很快,但要一个一个读然后赋值的scanf好一些

两个都试试吧,先cin读两个string

我操你马的折腾了这么久,简简单单直接一次AC

AC代码

复制代码
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 string a;
 6 string b;
 7 int ne[1001];
 8 int main()
 9 {
10     while(cin>>a && a!="#"){
11         cin>>b;
12         int len_a=a.length();
13         int len_b=b.length();
14 //        for(int i=0;i<len;i++){
15 //            if(str[i]<33 || str[i]>126)
16 //                break;
17 //
18 //            else{
19 //                a[i]=str[i];
20 //                len_a++;
21 //            }
22 //        }
23 //        for(int i=len_a+1;i<len;i++){
24 //            if(str[i]<33 || str[i]>126)
25 //                continue;
26 //            b[len_b]=str[i];
27 //            len_b++;
28 //        }
29 
30         int p=0;
31         if(len_a<len_b){
32             cout<<0<<endl;
33             p=1;
34         }
35         if(p==1)
36             continue;
37 
38 //        处理next数组
39         int k=-1;
40         int j=0;
41         ne[0]=-1;
42         while(j<len_b-1){
43             if(k==-1 || b[j]==b[k]){
44                 j++;
45                 k++;
46                 if(b[j]==b[k])
47                     ne[j]=ne[k];
48                 else
49                     ne[j]=k;
50             }
51             else
52                 k=ne[k];
53         }
54 
55 //        for(int i=0;i<len_a;i++)
56 //            cout<<a[i];
57 //        cout<<endl;
58 //        for(int i=0;i<len_b;i++)
59 //            cout<<b[i];
60 //        cout<<endl;
61 //        for(int i=0;i<len_a;i++)
62 //            cout<<"$"<<ne[i];
63 //        cout<<endl;
64 
65 //cout<<"&"<<len_b<<endl;
66 //        开始匹配
67         int i=0;
68         j=0;
69         int ans=0;
70         while(i<len_a){
71             if(j==len_b){
72                 ans++;
73                 j=0;
74 //                cout<<"#"<<i<<" "<<j<<endl;
75             }
76             if(j==-1 || a[i]==b[j]){
77                 i++;
78                 j++;
79 //                cout<<"@"<<i<<" "<<j<<endl;
80             }
81             else
82                 j=ne[j];
83         }
84 
85         //发现最后一个如果可以匹配,但也出循循环了,所以ans还得再加1
86         if(i==len_a && j==len_b){
87             ans++;
88             cout<<ans<<endl;//写完发现不用最开始那个布条<饰条的特判也行
89         }
90 //        if(i==len_a && j!=len_b)
91 //            cout<<0<<endl;
92 
93         else//比如asd a最后是i==3,j==0
94             cout<<ans<<endl;
95     }
96 }
复制代码

 

scanf写法也懒得写了

 

这他妈啥比赛的题啊?不百度谁知道ASC,看了下,应该是寒假在家训练题

 

###:在线PS

###:再次释怀,这题光输入那里,写代码的时候思路很清晰,但你如果说让我看别人的代码,甚至一个月后看自己的(光输入数据这)代码我都看不懂,但再写肯定能写出来,看代码好难,抽象的代码本身就比写更难

###:那些大厂的985的只是在人生的早年找到了最应试教育的考试方法,面试方法,跟“985的就厉害这句话”完全就不沾边,好多狗屁不是的都能进去,就因为是个研究生,呵呵,垃圾研究生那时候连408都不考,就一门数据结构

posted @   GerJCS  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示