B~F Java题解,代码已去除冗余~~~

B 球格模型(简单版)

球的数量必须至少保证每行每列都有,因此需要特判站不全的情况,否则尽量在遍历行列的情况下挨个放球,时间复杂度O(nm)

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt();
        if(k<Math.max(n,m)){
            System.out.println("-1");
        }
        else{
            int ans[][]=new int[n][m];
            for(int i=n-1,j=m-1;i>=0||j>=0;i--,j--,k--){
                ans[Math.max(i,0)][Math.max(j,0)]++;
            }
            ans[0][0]+=k;
            StringBuilder sb=new StringBuilder();
            for(int a[]:ans){
                for(int b:a){
                    sb.append(b+" ");
                }
                sb.append("\n");
            }
            System.out.println(sb);
        }
    }
}

C 小数字

只需要每一步过后的数字尽可能小,那么在数字小于3的时候只有减1才能最小,否则开方最小,时间复杂度O(T*min(logn,m))

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++){
            int n=sc.nextInt(),m=sc.nextInt();
            for(;m!=0;m--){
                if(n<=2){
                    n-=m;
                    break;
                }
                n=(int)Math.sqrt(n-0.5)+1;
            }
            System.out.println(n);
        }
    }
}

D 预知

考虑特殊情况:只有一种球时无法取胜,答案为-1;每种球只有一个的时候可以随便拿都能取胜,答案为0;次多的球有一个的时候,最坏的情况为预测了最多个球减一个,其中都是最大频率的球,这时只需要在剩下的球随便选即可,因此答案是最大频数减一;否则需要按照最坏情况,预测的球全部颜色一样,答案是最大频率,时间复杂度O(Tnlogn)

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++){
            int n=sc.nextInt(),a[]=new int[n];
            for(int j=0;j<n;j++){
                a[j]=sc.nextInt();
            }
            Arrays.sort(a);
            System.out.println(n==1?-1:a[n-2]==1?a[n-1]-1:a[n-1]);
        }
    }
}

E 而后单调

首先数组内数字不吭重复,其次需要找到一个单调的区间,再去掉这个区间后的,剩下的数字的值必须全部分布在区间的两侧,正反遍历一遍即可,可用有序集合实现,时间复杂度O(Tnlogn)

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        for(int i=0;i<t;i++){
            int n=sc.nextInt(),m=sc.nextInt(),a[]=new int[n];
            TreeSet<Integer> set=new TreeSet<>();
            set.add(0);
            set.add((int)2e9);
            for(int j=0;j<n;j++){
                a[j]=sc.nextInt();
                set.add(a[j]);
            }
            System.out.println(set.size()==n+2&&(check(a,m,0,1,set)||check(a,m,a.length-1,-1,set))?"YES":"NO");
        }
    }
    static boolean check(int a[],int m,int start,int inc,TreeSet<Integer> set){
        for(int i=start,j=start+inc;i>=0&&i<a.length;i=j,j+=inc){
            while(j>=0&&j<a.length&&a[j]>a[j-inc]){
                j+=inc;
            }
            if(Math.abs(i-j)>=m){
                for(int k=i;k!=i+m*inc;k+=inc){
                    set.remove(a[k]);
                }
                if(set.lower(a[i+(m-1)*inc])<a[i]&&set.higher(a[i])>a[i+(m-1)*inc]){
                    return true;
                }
                for(int k=i+m*inc;k!=j;k+=inc){
                    set.remove(a[k]);
                    set.add(a[k-m*inc]);
                    if(set.lower(a[k])<a[k-(m-1)*inc]&&set.higher(a[k-(m-1)*inc])>a[k]){
                        return true;
                    }
                }
                for(int k=i;k!=j;k+=inc){
                    set.add(a[k]);
                }
            }
        }
        return false;
    }
}

F 最大最小路

考虑正难则反:不好的路径是什么样的?不好的路径要么权值全部小于b,要么权值全部大于啊,要么两个都是,因此就是总路径数减去符合上边的所有路径,可深搜,依次统计以每一个节点为路径最高点的时,且节点数值在某个范围内的路径数量,时间复杂度O(n),,,本题略微卡常,需要在时间上优化读写以防TLE,同时实现过程中减少多开数组以防MLE,另外由于统计数据过程的相似性,可整合代码,一次深搜完成

import java.util.*;
import java.io.*;
public class Main{
    public static void main(String args[]) throws IOException{
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st=new StringTokenizer(bf.readLine());
        int n=Integer.parseInt(st.nextToken()),a=Integer.parseInt(st.nextToken()),b=Integer.parseInt(st.nextToken()),w[]=new int[n+5];
        List<Integer> path[]=new List[n+5];
        st=new StringTokenizer(bf.readLine());
        for(int i=1;i<=n;i++){
            w[i]=Integer.parseInt(st.nextToken());
            path[i]=new ArrayList<>();
        }
        for(int i=0;i<n-1;i++){
            st=new StringTokenizer(bf.readLine());
            int u=Integer.parseInt(st.nextToken()),v=Integer.parseInt(st.nextToken());
            path[u].add(v);
            path[v].add(u);
        }
        bw.write(((long)n*(n-1)+find(1,0,new int[][]{{0,b-1,-1},{a+1,(int)2e9,-1},{a+1,b-1,1}},w,path)[3])/2+"\n");
        bw.flush();
    }
    static long[] find(int k,int pre,int task[][],int w[],List<Integer> path[]){
        long ans[]=new long[4];
        for(int a:path[k]){
            if(a!=pre){
                long cur[]=find(a,k,task,w,path);
                ans[3]+=cur[3];
                for(int i=0;i<3;i++){
                    if(w[k]>=task[i][0]&&w[k]<=task[i][1]){
                        ans[3]+=task[i][2]*(ans[i]*cur[i]*2+cur[i]*2);
                        ans[i]+=cur[i];
                    }
                }
            }
        }
        for(int i=0;i<3;i++){
            if(w[k]>=task[i][0]&&w[k]<=task[i][1]){
                ans[i]++;
            }
            else{
                ans[i]=0;
            }
        }
        return ans;
    }
}