今天为大家讲解一下尺取法。尺取尺取,尺子取值?其实啊,算法中的尺取法,我们可以用它来解决区间的问题。尺取法在算法竞赛中是一个常用的优化技巧,它操作简单、容易编程。下面让我们来看一下吧!
目录
一、什么是尺取法?
- 将普通的双重循环
for(int i=0;i<n;i++){ //i从前往后
for(int j=n-1;j>= 0;j--){ //j从后往前
//(某神秘操作)
}
}
- 变成一个循环
for(int i=0,j=n-1;i<j;i++,j--){ //i从前往后,j从后往前
//(某神秘操作)
}
二、如何表示它呢?
不同编程语言的循环语句有点相同,说到循环,咱大脑一想,for和while做常用!
- for循环使用方法
for(int i=0,j=n-1;i<j;i++,j--){ //i从前往后,j从后往前
//(某神秘操作)
}
- while循环使用方法
int i=0,j=n-1;
while(i<j){
//(某神秘操作)
i++;
j--;
}
三、使用操作方法?
- 同向扫描
i,j的方向相同(同++或同--),速度可能不一样,像极了初中学的“追及问题”。
import java.util.*;
public class Dome {
public static void main(String[] args) {
int t = 0;
System.out.println("请输入数组长度:");
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] a=new int[n];
System.out.println("请输入数组内容:");
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
System.out.println("请输入一个数:");
Scanner scc=new Scanner(System.in);
int s=sc.nextInt();
int sum=a[0],i=0,j=0;
while(j<n) {
if(sum>=s) {
if(sum==s) {
System.out.print("区间起点:");
System.out.println(i);
System.out.println(" ");
System.out.println("区间终点:");
System.out.print(j);
}
sum-=a[i];
i++;
if(i>j) {
sum=a[i];
j++;
}
}
if(sum<s) {
j++;
sum+=a[j];
}
}
}
}
- 反向扫描
i,j的方向不同(一个++一个--),速度可能不一样,像极了初中学的“相遇问题”。
import java.util.*;
public class Dome {
public static void main(String[] args) {
int t = 0;
System.out.println("请输入字符串:");
Scanner s=new Scanner(System.in);
String l = s.nextLine();
char[] line=l.toCharArray();
int length=l.length();
if(length==0||length==1) {
t=1;
}
else if(length>1){
for(int i=0,j=length-1;i<j;i++,j--) {
if(line[i]==line[j]) {
t=1;
}
else {
t=0;
}
}
}
if(t==1) {
System.out.println("是回文数!");
}
else if(t==0) {
System.out.println("不是回文数!");
}
}
}
四、蓝桥真题重现!
public class Demo8 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();//输入日志行数
int D=sc.nextInt();//输入时间段D
int K=sc.nextInt();//输入热帖点赞数
//map用于存放每一个帖子初始点赞时间
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
//map1用于存放各帖子在规定时间段D的点赞数
Map<Integer,Integer> map1=new HashMap<Integer,Integer>();
for(int i=0;i<N;i++) {
int a=sc.nextInt();//输入帖子点赞时间
int b=sc.nextInt();//输入帖子id
if(map.get(b)==null) {//若map中不存在输入的帖子id,即该帖子是首次被点赞
map.put(b, a);//将首次被点赞的帖子的id和首次被点赞的时间存入map中
map1.put(b, 1);//首次被点赞的帖子的点赞数目为1,将该帖子id及点赞数加入到map1中
}else {//若map中存在输入的帖子id,即该帖子不是首次被点赞
//判断输入的点赞时间是否满足在时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间),若满足则将map1中对应id的帖子的点赞数加1
if(map.get(b)==a||map.get(b)+D>a) {
map1.put(b, map1.get(b)+1);
}
}
}
sc.close();
//遍历map1,若满足帖子的点赞数不少于K,则该贴曾是热帖,输出该贴子的id
for (Integer key : map1.keySet()) {
if(map1.get(key)>=K) {
System.out.println(key);
}
}
}
}