2019牛客多校 第四场 A.C.D.J.K(Java版)

A-meeting
题目链接 https://ac.nowcoder.com/acm/contest/884/A
给你n个点n-1条边,每条边的长度为1,有k个人在不同的点上,问你选择一个点聚会,求k个人中到达这个点的距离的最大值,要让这个最大值最小,可以用类似求树的直径的写法做,跑两边bfs,第一次从k个点中任选一点跑到的最远的剩下k-1个点中的点,第二次从这个最远的点再跑到的最远的剩下的k-1个点,最后的距离就是(d+1)/2

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int maxn=100005;
	static boolean v[]=new boolean[maxn];
	static boolean use[]=new boolean[maxn];
	static int n,k,eid,ans,tp;
	static int p[]=new int[maxn];
	static class edge{
		int v,next;
		public edge(int v, int next) {
			super();
			this.v = v;
			this.next = next;
		}	
	}
	static edge e[]=new edge[maxn<<1];
	static void add(int u,int v){
		e[eid]=new edge(v,p[u]);
		p[u]=eid++;
	}
	static int bfs(int u){
		int res=u;
		Queue q=new LinkedList<>();
		q.add(u);
		use[u]=true;
		int cnt=0;
		while(!q.isEmpty()){
			int len=q.size();
			cnt++;
			while(len-->0){
				int x=q.poll();
				for(int i=p[x];i!=-1;i=e[i].next){
					int j=e[i].v;
					if(use[j])
						continue;
					q.add(j);
					if(v[j]){
						ans=cnt;
						res=j;
					}
					use[j]=true;
				}
			}
		}
		return res;
	}
	static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	public static void main(String[] args) {		
		
		eid=0;
		n=nextInt();
		k=nextInt();
		for(int i=0;i

C.sequence
题目链接:https://ac.nowcoder.com/acm/contest/884/C
题目给你两个数组a,b。问你 a数组的区间最小值*b数组的区间和 的最大值是多少。考虑a数组的最小值大于0和小于0两种情况,用类似求最大连续子段和的方式两遍for循环就可以。 出题人的标解是用单调栈求a数组的区间最小值,用前缀和保存b数组的区间和,然后用线段树或者笛卡儿树查询。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
	static long inf=(long)1e18;
	static int maxn=(int) (3e6+5);
	static long a[]=new long[maxn];
	static long b[]=new long[maxn];
	static long n,temp,ans=0,sum;
	static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	public static void main(String[] args) {
		n=nextInt();
		for(int i=0;i=0){
				sum+=b[i];
				temp=Math.min(temp, a[i]);
			}else{
				sum=0;
				temp=inf;
			}
			ans=Math.max(ans, sum*temp);
		}
		for(int i=0;i0){
	            temp=Math.max(temp,a[i]);
	            sum+=b[i];
	        }else{
	            sum=0;
	            temp=-inf;
	        }
	        ans=Math.max(ans,sum*temp);
	    }
	    System.out.println(ans);
	}
	static int nextInt(){
		try {
			st.nextToken();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return (int)st.nval;
	}
}

D.triples I
题目链接 https://ac.nowcoder.com/acm/contest/884/D
给你一个数a,问a能由哪些3的倍数的数通过位操作得到,当a本身是3的倍数时,直接输出“1 a”,可以证明任意一个数a都能由两个3的倍数位操作得到,然后
分类讨论下

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
//二进制位的奇数位mod3等于1,偶数位mod3等于2
public class Main {
	static int mxs=60;	
	public static void main(String[] args) {
		InputReader in=new InputReader();
		PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
		int t=in.nextInt();
		while(t-->0){
			long a=in.nextLong();
			if(a%3==0)
				out.println("1 "+a);
			else{
				int ns=(int) (a%3);
				long n=a,m=a;
				int tt=0;
				int fl=0;
				for(int i=0;i

J.free
题目链接 https://ac.nowcoder.com/acm/contest/884/J
分层图的模版题,每条边有边权,给你k次机会直接通过一条边而不计算边权,问起点和终点之间的最短路径

import java.util.PriorityQueue;
import java.util.Scanner;

//分层图模版题,每条边有边权,给你k次机会直接通过一条边而不计算边权,问起点和终点之间的最短路径
public class Main {
	static int n,m,s,t,k,eid;
	static class edge{
		int v,next,w;

		public edge(int v, int next, int w) {
			super();
			this.v = v;
			this.next = next;
			this.w = w;
		}
		
	}
	static class node implements Comparable{
		int u,d,k;

		public node(int u, int d, int k) {
			super();
			this.u = u;
			this.d = d;
			this.k = k;
		}
		public int compareTo(node o) {
			return this.d-o.d;
		}
	}
	static boolean vis[][]=new boolean[1005][1005];
	static int p[]=new int[1005];
	static int dis[][]=new int[1005][1005];
	static edge e[]=new edge[1005*2];
	static void init(){
		eid=0;
		for(int i=0;i<1005;i++)
			p[i]=-1;
	}
	static void insert(int u,int v,int w){
		e[eid]=new edge(v,p[u],w);
		p[u]=eid++;
	}
	static int dijkstra(int s,int t){
		for(int i=0;i<1005;i++){
			for(int j=0;j<1005;j++){
				dis[i][j]=0x3f3f3f3f;
			}
		}
		dis[s][0]=0;
		PriorityQueue pq=new PriorityQueue<>();
		pq.add(new node(s,0,0));
		while(!pq.isEmpty()){
			node cur=pq.poll();
			int u=cur.u;
			int d=cur.d;
			int nk=cur.k;
			if(u==t)
				return cur.d;
			if(vis[u][nk])
				continue;
			vis[u][nk]=true;
			for(int i=p[u];i!=-1;i=e[i].next){
				int v=e[i].v;
				if(nkd){
						dis[v][nk+1]=d;
						pq.add(new node(v,dis[v][nk+1],nk+1));
					}
				}
				if(dis[v][nk]>d+e[i].w){
					dis[v][nk]=d+e[i].w;
					pq.add(new node(v,dis[v][nk],nk));
				}
			}
		}
		return 0;
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		s=sc.nextInt();
		t=sc.nextInt();
		k=sc.nextInt();
		init();//总是忘记初始化
		for(int i=0;i

K.number
题目链接 https://ac.nowcoder.com/acm/contest/884/K
给你一个数字字符串,问你有多少子串是300的倍数,0也算。

import java.util.Scanner;
//要满足是300的倍数,各个位数之和是3的倍数,且末尾2个零及以上
public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		String s=sc.nextLine();
		char ctr[]=s.toCharArray();
		int len=ctr.length;
		long ans=0;
		int sum=0;
		int cnt[]=new int[3];
		cnt[0]=1;
		for(int i=0;i

你可能感兴趣的:(牛客)