解题思路:
常规思想:两个不定长数组,j下标从0开始Alice找Bob,时间超限55
Bob运用数组方法:数组下标差的到的中间那段,找Bob为1的index有几个,然后相加,时间超限82
滑动窗口算法思想优化算法:循环Alice时候,下一次的Alice寻找Bob的开始和结束位置是上一次Alice的寻找Bob的开始和结束位置。
注意事项:sc.nextInt()和sc.nextLine()的结合使用时需要吞掉一个换行符。
参考代码:
import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int k=sc.nextInt();String kong=sc.nextLine(); long count=0; String str=sc.nextLine(); ArrayList<Integer> alice=new ArrayList<Integer>(); ArrayList<Integer> bob=new ArrayList<Integer>(); //int[] bob=new int[1000000]; int froma=0,fromb=0; while(true){ int indexa=str.indexOf("Alice",froma); froma=indexa+4; if(indexa==-1){froma=str.length()-1;} int indexb=str.indexOf("Bob",fromb); fromb=indexb+2; if(indexb==-1){fromb=str.length()-1;} if(indexa==-1&&indexb==-1){ break; } if(indexa!=-1&&indexa+4<=str.length()-1){ if((indexa+5==str.length()&&feizimu(str.charAt(indexa-1)))||(indexa==0&&feizimu(str.charAt(indexa+5)))||(feizimu(str.charAt(indexa-1))&&feizimu(str.charAt(indexa+5)))){ alice.add(indexa); } } if(indexb!=-1&&indexb+2<=str.length()-1){ if((indexb+3==str.length()&&feizimu(str.charAt(indexb-1)))||(indexb==0&&feizimu(str.charAt(indexb+3)))||(feizimu(str.charAt(indexb-1))&&feizimu(str.charAt(indexb+3)))){ bob.add(indexb); //bob[indexb]++; } } } //int As = alice.size(), Bs = bob.size(); //As与Bs分别为两数组元素个数 //int bl = 0, br = 0; int j=0,m=0; for(int i=0;i<alice.size();i++){ /*int j=alice.get(i)-k-3; if(j<0){ j=0; } int m=alice.get(i)+k+5; if(m>=str.length()){ m=str.length()-1; //此方法(Alice找Bob,Bob位置用下标定义)时间超限82 } for(;j<=m;j++){ if(bob[j]!=0){ count++; } }*/ /*while(bl < Bs && bob.get(bl)< alice.get(i) - k - 3) bl++; //维护窗口左边界 while(br < Bs && bob.get(br) <= alice.get(i) + k + 5) br++; //维护窗口右边界 count += br - bl; */ //下一次Alice的j和m都是从上一次的j和m开始,ac通过 /*for(int j=0;j<bob.size();j++){ if(bob.get(j)<alice.get(i)&&alice.get(i)-bob.get(j)<=k+3){ count++; } if(bob.get(j)>alice.get(i)&&bob.get(j)-alice.get(i)<=k+5){ count++; //j每次从0开始,时间超限82 } if(bob.get(j)-alice.get(i)>k+5){ break; } }*/ for(;j<bob.size();j++){ if(alice.get(i)-bob.get(j)<=k+3){ break; } //下一次Alice的j和m都是从上一次的j和m开始,ac通过 // 使用滑动窗口的算法思想来优化算法,否则将超时。 } for(;m<bob.size();m++){ if(bob.get(m)-alice.get(i)>k+5){ break; } } count+=m-j; } System.out.println(count); } public static boolean feizimu(char ch){ if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ return false; }else{ return true; } } }
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复