第 26 场 蓝桥月赛
- 2.灯笼猜谜
- 3.元宵分配
- 4.摆放汤圆
- 5.元宵交友(运行超时 通过90%)
2.灯笼猜谜
分析:以当前位置为视角,要想移动的距离尽可能的少,按顺序猜谜语,给你一个区间,有三种情况:
①当前位置在区间上就不用移动
②当前位置在区间左边,移动到区间左边界
③当前位置在区间右边,移动到区间右边界
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {public static void main(String[] args) {Scanner scan=new Scanner(System.in);int n=scan.nextInt();int m=scan.nextInt();int cur=1;long res=0;for(int i=0;i<n;i++){int l=scan.nextInt();int r=scan.nextInt();if(cur>=l&&cur<=r){//当前位置在区间上 不用移动}else if(cur<l){//当前位置在区间左边res+=(l-cur);cur=l;}else if(cur>r){//当前位置在区间右边res+=(cur-r);cur=r;}}System.out.println(res);scan.close();}
}
3.元宵分配
分析:给你一些汤圆,你要知道无论怎么倒,最后得到的数量不会增加。
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
//无论你怎么到都不会变多
public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...int n=scan.nextInt();int k=scan.nextInt();int getSz=n/2;int[]arr=new int[n];for(int i=0;i<n;i++){arr[i]=scan.nextInt();}Arrays.sort(arr);long res=0;for(int i=0;i<getSz;i++){res+=arr[i];}System.out.print(res);scan.close();}
}
4.摆放汤圆
分析:通过画图找到规律,可以在对角线上放,要么在(1,j)和(j,1)上放,这次在前面的基础上来放,难点就是找规律,
dp[i]=dp[i-1]+(n-1) * dp[i-2] ,dp[i]表示在i*i的盘子上的摆法。
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {static final int N=1000001;static final int mod=1000000007;static long[]dp=new long[N];//dp[i]:在i*i的盘子上摆放i个的方案public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...int t=scan.nextInt();//dp[i]=dp[i-1]+(n-1)*dp[i-2]dp[1]=1;dp[2]=2;int maxDish=0;int[] arr=new int[t];for(int i=0;i<t;i++){int curDish=scan.nextInt();arr[i]=curDish;maxDish=Math.max(maxDish,curDish);}update(maxDish);for(int i=0;i<t;i++){System.out.println(dp[arr[i]]);}scan.close();}static void update(int index){for(int i=3;i<=index;i++){dp[i]=dp[i-1]+(i-1)*dp[i-2]%mod;dp[i]%=mod;}}
}
5.元宵交友(运行超时 通过90%)
分析:
相同的参与度算一个,所以涉及到去重,在给定的k下,找出满足条件的最多人数。
对它们的参与度排序,差异越大越好,最小的肯定选中,然后用二分找到大于等于k+curVal的最近下标,更新当前位置,然后又往后找大于等于k+curVal的最近下标,就这样直到没有了。时间复杂度有点高,所以没全过。
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);//在此输入您的代码...//1.先排序去重 去重用set 排序用list collectionsint n=scan.nextInt();//人数Set<Integer> set=new HashSet();for(int i=0;i<n;i++){set.add(scan.nextInt());}List<Integer> list=new ArrayList(set);Collections.sort(list);//2.对每一个k 贪心选择+二分查找for(int k=1;k<=n;k++){int curIndex=0;int sz=list.size();int count=1;//从最小的开始while(true){//当前的值int curVal=list.get(curIndex);//找>=k+curVal的人 得到下标int nextIndex= check(list,k+curVal,curIndex+1);if(nextIndex>=list.size()){//没有找到 结束了break;}//找到了count++;curIndex=nextIndex;}System.out.print(count+" ");}scan.close();}//定义:在list中找到>=aimVal的最小索引static int check(List<Integer> list,int aimVal,int startIndex){int sz=list.size();int l=startIndex,r=sz;while(l<r){int mid=(l+r)>>1;if(list.get(mid)>=aimVal){r=mid;}else{l=mid+1;}}return l;}
}