牛客某白月赛52

目录

A、签到时刻

B、牛牛的身高

C、说谎的机器

D、环上食虫

E、分组求对数和

F、骑士战胜魔王


A、签到时刻

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int t=cin.nextInt();
    	
    	while(t-->0) {
    		int n=cin.nextInt();
    		int cnt1=0,cnt2=0;
    		
    		while(n-->0) {
    			String s=cin.next();
        		String ss[]=s.split(":");
        		
        		if(Integer.parseInt(ss[0])<8||(Integer.parseInt(ss[0])==8&&Integer.parseInt(ss[1])==0))continue;
        		if(Integer.parseInt(ss[0])==8&&Integer.parseInt(ss[1])<=5&&Integer.parseInt(ss[1])>0)cnt1++;
        		else cnt2++;
    		}
    		
    		out.println(cnt1+" "+cnt2);
    	}
    	out.flush();
	}
}

B、牛牛的身高

思路:通过读题我们可以知道,当某个位数>=5时就可以进位,而此时进位后面的所有数都要射去,所以我们只需要从最低位到最高位进行遍历,判断是否有进位并记录即可。

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int t=cin.nextInt();
    	
    	while(t-->0) {
    		String s=cin.next();
    		
    		char c[]=s.toCharArray();
    		int m=0,f=-1;//m用来记录在i处是否有进位,f用来记录最大进位的位置
    		for(int i=c.length-1;i>=0;i--) {
    			m+=c[i]-'0';
    			if(m>=5) {
    				f=i;
    				c[i]='0';
    				m=1;
    			}else {
    				c[i]=(char)(m+'0');
    				m=0;
    			}
    		}
    		
    		if(m>0)out.print(m);
    		if(f<0)f=c.length;
    		
    		for(int i=0;i<f;i++) {
    			out.print(c[i]);
    		}
    		
    		for(int i=f;f>=0&&i<c.length;i++)
    			out.print(0);
    		out.println();
    		out.flush();
    	}
    	
	}
}

C、说谎的机器

思路:通过题意我们可以知道,当求机器的错误指令数最多,那么也就是求,一个取值所涵盖的正确次数最少。而且通过题意我们可以发现,每次的机器指令覆盖的都是一段区间,所以我们可以通过差分来求解,最后使用前缀和来得出每个数字被机器指令覆盖的次数,找出最小值,最后输出即可。

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int n=cin.nextInt(),m=cin.nextInt();
    	
    	int a[]=new int[n+2];
    	for(int i=0;i<m;i++) {
    		int op=cin.nextInt();
    		if(op==1) {
    			int x=cin.nextInt(),y=cin.nextInt();
    			a[x]++;a[y+1]--;
    		}else if(op==2){
    			int x=cin.nextInt();
    			a[x]++;a[n+1]--;
    		}else {
    			int y=cin.nextInt();
    			a[1]++;a[y+1]--;
    		}
    	}
    	
        //map用来记录出现的数字的次数
    	HashMap<Integer,Integer> map=new HashMap<>();
    	int min=Integer.MAX_VALUE;
    	for(int i=1;i<=n;i++) {
    		a[i]+=a[i-1];
    		min=Math.min(min,a[i]);
    		map.put(a[i],map.getOrDefault(a[i],0)+1);
    	}
    	
    	out.println((m-min)+" "+map.get(min));
    	out.flush();
   	
	}
}

D、环上食虫

思路:分析可得蛋糕是圆圈排列,要求在能够吃饱的情况下,他吃到蛋糕中奶油含量最高的那一个最低会是多少,我们需要模拟出所有得满足它能吃饱得区间,然后求在这些区间中出现的蛋糕中奶油含量最高的那一个的最小值。

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int n=cin.nextInt(),s=cin.nextInt();
    	
    	long sum=0;
    	long a[]=new long[n*2+1];//记录蛋糕的饱腹值
    	long b[]=new long[n*2+1];//记录蛋糕的奶油含量
    	long f[]=new long[n*2+1];//记录蛋糕的饱腹值的前缀和
    	
    	for(int i=1;i<=n;i++) {
    		a[i]=cin.nextLong();
    		a[i+n]=a[i];
    		f[i]=f[i-1]+a[i];
    	}
    	
    	for(int i=1;i<=n;i++) {
    		b[i]=cin.nextLong();
    		b[i+n]=b[i];
    	}
    	
    	if(f[n]<s)out.println(-1);
    	else {
            //用来记录某一段取值中各个奶油含量值及个数
    		HashMap<Long,Integer> map=new HashMap<>();
    		
    		long max=-1,ans=-1;
    		int i=1;
            
            //找出第一个>=s的位置
    		for(;i<=n;i++) {
    			max=Math.max(max,b[i]);
    			map.put(b[i],map.getOrDefault(b[i],0)+1);
    			if(f[i]>=s)break;
    		}
    		ans=max;
    		int j=i+1;//用来记录右端点移动的位置
    		long sf=f[i];//当前区间的饱腹值总和
    		
    		i=1;
    		while(i<=n) {
    			
                //左端每次点向右移动一位,寻找下一个满足题意的区间
    			while(i<=n&&sf>=s) {
    				ans=Math.min(ans,max);
    				sf-=a[i];
    				map.put(b[i],map.getOrDefault(b[i],0)-1);
    				
                   //删除个数为零的奶油值
    				if(map.getOrDefault(b[i],0)==0)map.remove(b[i]);
                    
    				 //如果移动的左端点刚好的该区间的唯一一个最大奶油含量,重新查找该段区间中最大的奶油含量
    				if(max==b[i]&&!map.containsKey(b[i])) {
    					max=0;
    					for(long x:map.keySet()) {
    						max=Math.max(max,x);
    					}
    				}
    				i++;
    			}
    			
                //找寻下一个满足题意得一段区间
    			while(j<2*n&&sf<s) {
    				sf+=a[j];
    				map.put(b[j],map.getOrDefault(b[j],0)+1);
    				max=Math.max(max,b[j]);
    				j++;
    			}
    			
                //区间最多只包含n个蛋糕
    			if(j-i>n)break;
    		}
    		
    		out.println(ans);
    	}
    	out.flush();
   	
	}
}

E、分组求对数和

思路:分析可知,找出不同组的两个数字和大于>=k,所以我们可以用一个数组将所有的s都存起来,用一个二维数组存第i个小朋友手中的数字,并将其全部进行排序;然后遍历每一个小朋友手中的数字,得到m=k-x;通过二分查找找出小朋友手中大于m的数量和总体大于m的数量,最后相减即可能与该数字组合满足条件的其他小朋友手中的数字的数量。又由于每一对数字被算了两次,所有最后得到的答案总和/2;

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int n=cin.nextInt(),k=cin.nextInt();

    	int mod=998244353;
    	Vector<Integer> a[]=new Vector[n];
    	Vector<Integer> b=new Vector<>();
    	long ans=0;
    	
    	for(int i=0;i<n;i++) {
    		a[i]=new Vector<>();
    		
    		int s=cin.nextInt();
    		for(int j=0;j<s;j++) {
    			int x=cin.nextInt();
    			a[i].add(x);
    			b.add(x);
    		}
    		
    		Collections.sort(a[i]);
    	}
    	
    	Collections.sort(b);
    	
    	for(int i=0;i<n;i++) {
    		for(int j=0;j<a[i].size();j++) {
    			int m=k-a[i].get(j);
    			
    			long num1=ms(m,a[i]);
    			long num2=ms(m,b);
    			
//    			out.println(num1+" "+num2);
    			ans+=num2-num1;
    		}
    	}
    	out.println((ans/2)%mod);
    	out.flush();
   	
	}

	private static long ms(int m, Vector<Integer> b) {
		// TODO Auto-generated method stub
		int l=0,r=b.size()-1;
		
		while(l<r) {
			int mid=(l+r)>>1;
			if(b.get(mid)<m)l=mid+1;
			else r=mid;
		}
		
		if(l==r&&b.get(r)<m)return 0;
		return b.size()-r;
	}
}

F、骑士战胜魔王

思路:题意:1、找出骑士技能之和>=m的方案数;

                      2、当骑士能量消耗之和不同时方案才不同;

            通过分析,将能量消耗固定,找出在某个能量消耗下最大攻击值(最大攻击值能满足条件,就不同管比较小的了),那么,就可以确保能找出总的方案数;

import java.util.*;
import java.io.*;

public class Main {
    static class FastReader{
        BufferedReader br;
        StringTokenizer st;
        String tmp;

        public FastReader() {
            br=new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st==null||!st.hasMoreElements()) {
                try {
                    st=new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong(){return Long.parseLong(next());}

        String nextLine() {
            String str="";
            try {
                str=br.readLine();
            }catch(IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        boolean hasNext(){
            if(st!=null&&st.hasMoreTokens())return true;
            try {
                tmp=br.readLine();
                st=new StringTokenizer(tmp);
            }catch(IOException e) {
                return false;
            }
            return true;
        }
    }

    static PrintWriter out=new PrintWriter(
            new BufferedWriter(new OutputStreamWriter(System.out)));
    static FastReader cin=new FastReader();

    public static void main(String[] args) {
    	int n=cin.nextInt(),m=cin.nextInt();
    	
    	int mod=998244353;
    	
    	long f[][]=new long[n+1][m+1];//代表1-i个骑士所有技能中,攻击值为j的个数
    	f[0][0]=1;
    	for(int i=1;i<=n;i++) {
    		int s=cin.nextInt();
    		int sum=0;//该骑士使用所有技能所消耗的总值
    		
    		int a[]=new int[s+1];//攻击值
    		int b[]=new int[s+1];//消耗值
    		for(int j=1;j<=s;j++)a[j]=cin.nextInt();
    		for(int j=1;j<=s;j++) {
    			b[j]=cin.nextInt();
    			sum+=b[j];
    		}
    		
    		long g[]=new long[sum+1];//用来记录消耗值为i的情况下的最大攻击值
    		Arrays.fill(g,Integer.MIN_VALUE);
    		
    		g[0]=0;//初始化
            
            //01背包问题求解在固定的消耗值的情况下最大攻击值
    		for(int j=1;j<=s;j++) {
    			for(int k=sum;k>=b[j];k--) {
    				g[k]=Math.max(g[k],g[k-b[j]]+a[j]);
    			}
    		}
    		
            //遍历攻击值,进行累加
    		for(int j=0;j<=sum;j++) {
    			if(g[j]<0)continue;
    			
    			for(int k=0;k<=m;k++) {
                    
                    //当k+g[j]>=m说明满足条件
    				int x=(int)Math.min(m,k+g[j]);
    				f[i][x]=(f[i][x]+f[i-1][k])%mod;
    			}
    			
    		}
    		
    	}
    	
    	out.println(f[n][m]);
    	out.flush();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目要求:给定一个二叉树和一个整数target,找出所有从根节点到叶子节点路径之和等于target的路径。 解题思路:可以使用深度优先搜索(DFS)的方法来解决该问题。首先定义一个辅助函数来进行递归搜索,该辅助函数的参数包括当前节点、当前路径、当前路径的和以及目标和。在搜索过程中,需要维护一个数组来保存当前节点到根节点的路径。搜索过程如下: 1. 如果当前节点为空,则返回。 2. 将当前节点的值添加到当前路径中。 3. 将当前节点的值累加到当前路径的和中。 4. 如果当前节点是叶子节点,且当前路径的和等于目标和,则将当前路径添加到结果中。 5. 递归地搜索当前节点的左子树和右子树,并传递更新后的当前路径和当前路径的和。 最后,在主函数中调用辅助函数,并返回结果即可。 以下是题目的完整代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def pathSum(root, target): def dfs(node, path, path_sum, target, res): if not node: return path.append(node.val) path_sum += node.val if not node.left and not node.right: # 当前节点是叶子节点 if path_sum == target: res.append(path[:]) # 注意需要复制一份path,否则会出现问题 dfs(node.left, path, path_sum, target, res) dfs(node.right, path, path_sum, target, res) path.pop() # 回溯到父节点,去掉当前节点 path_sum -= node.val res = [] dfs(root, [], 0, target, res) return res ``` 这样就能找出所有满足路径和等于目标和的路径了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值