HDU2087-剪花布条
继续跟邝斌飞刷KMP
关于可见字符,大概从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 }
测试发现下面这组数据输出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 }
想到如果输入一个布条然后回车是不是也应该等待输入
可是输入“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 }
发现输入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都不考,就一门数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探