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