JAVA B组参考代码
文章目录 **JAVA B组参考代码 ** **试题 A: 重合次数** **试题 B: 数数** **试题 C: 左移右移** **思路:** **对于操作从后向前记录,最后操作的肯定是在两端,并对该操作的数进行记录,方便最后保留原来未操作过数的顺序** **参考代码:** **试题 D: 窗口** **思路:** **按照题目描述进行模拟,本人模拟很烂,就不写这题代码了** **试题 E: 迷宫** **思路:** **Map(i,j)表示的含义是从i,j到终点n,n的步数, 根据直接跳跃距离终点(n,n)最近的进行排序,然后判断直接传送后的是否比不用传送小进行更新,然后根据期望的含义进行计算** **参考代码:** **试题 F: 小球称重** **思路:** **本题主要考虑次品比较轻,所以在小于的那部分,其次然后后续根据大于和等于的情况,排除掉不可能的,因为TreeSet可以做到有序,查找和删除可以在log范围内进行,还要考虑一种特别特殊的情况,就是所有都是等于,说明次品在剩下的里面,所以就是n减去出现过的** **参考代码:** **试题 G: 背包与魔法** **思路:** **可以参考01背包的思路,加一维判断是否使用了这个魔法** **参考代码:** **试题H:修路** **思路:** **将各个顶点分为3类,第一类左上角的点,标记为0,a的为1到n,b的为m+(1到n),然后将其建边,主要是一侧的相邻之间进行建边,相对的可以任意两两之间建边,然后跑最小生成树,得到结果** **参考代码:** **试题I:围栏** **试题J: 好数之和** **思路:** **把其他数位进行枚举,然后将其2022插入进去进行判断即可,kkkk枚举的是插入位置,其他是代表其他几位上的数** **参考代码:**
试题 A: 重合次数
答案:494
试题 B: 数数
答案:25606
试题 C: 左移右移
思路:
对于操作从后向前记录,最后操作的肯定是在两端,并对该操作的数进行记录,方便最后保留原来未操作过数的顺序
参考代码:
import java. util. * ;
public class Main { static int a[ ] = new int [ 200005 ] ; static int vis[ ] = new int [ 200005 ] ; static String op[ ] = new String [ 200005 ] ; static int num[ ] = new int [ 200005 ] ; static int ans[ ] = new int [ 200005 ] ; public static void main ( String [ ] args) { Scanner in = new Scanner ( System . in) ; int n, q; n= in. nextInt ( ) ; q= in. nextInt ( ) ; for ( int i= 1 ; i<= n; i++ ) { a[ i] = i; } for ( int i= 1 ; i<= q; i++ ) { op[ i] = in. next ( ) ; num[ i] = in. nextInt ( ) ; } int left= 1 ; int right= n; for ( int j= q; j>= 1 ; j-- ) { if ( op[ j] . charAt ( 0 ) == 'L' ) { ans[ left] = num[ j] ; left++ ; vis[ num[ j] ] = 1 ; } if ( op[ j] . charAt ( 0 ) == 'R' ) { ans[ right] = num[ j] ; right-- ; vis[ num[ j] ] = 1 ; } } for ( int i= 1 ; i<= n; i++ ) { if ( vis[ i] == 0 ) { ans[ left] = a[ i] ; left++ ; } } for ( int i= 1 ; i<= n; i++ ) { if ( i== 1 ) { System . out. print ( ans[ i] ) ; } else { System . out. print ( " " + ans[ i] ) ; } } return ; }
}
试题 D: 窗口
思路:
按照题目描述进行模拟,本人模拟很烂,就不写这题代码了
试题 E: 迷宫
思路:
Map(i,j)表示的含义是从i,j到终点n,n的步数, 根据直接跳跃距离终点(n,n)最近的进行排序,然后判断直接传送后的是否比不用传送小进行更新,然后根据期望的含义进行计算
参考代码:
import java. util. * ;
public class Main { static int Map [ ] [ ] = new int [ 2005 ] [ 2005 ] ; static class node implements Comparable < node> { int x1, y1, x2, y2; int val; @Override public int compareTo ( node o) { return this . val- o. val; } } static node p[ ] = new node[ 2005 ] ; public static void main ( String [ ] args) { Scanner in = new Scanner ( System . in) ; int n, m; n = in. nextInt ( ) ; m = in. nextInt ( ) ; for ( int i = 1 ; i <= m ; i++ ) { p[ i] = new node ( ) ; p[ i] . x1 = in. nextInt ( ) ; p[ i] . y1 = in. nextInt ( ) ; p[ i] . x2 = in. nextInt ( ) ; p[ i] . y2 = in. nextInt ( ) ; p[ i] . val= 2 * n- p[ i] . x2- p[ i] . y1; } Arrays . sort ( p, 1 , m+ 1 ) ; for ( int i = 1 ; i <= n ; i++ ) { for ( int j = 1 ; j <= n; j++ ) { Map [ i] [ j] = Math . abs ( n- i) + Math . abs ( n- j) ; } } for ( int i = 1 ; i <= m; i++ ) { Map [ p[ i] . x1] [ p[ i] . y1] = Math . min ( Map [ p[ i] . x1] [ p[ i] . y1] , Map [ p[ i] . x2] [ p[ i] . y2] + 1 ) ; } double ans= 0 ; for ( int i = 1 ; i <= n; i++ ) { for ( int j= 1 ; j <= n; j++ ) { ans+= ( double ) ( Map [ i] [ j] ) ; } } System . out. printf ( "%.2f\n" , ans* 1.0 / ( n* n) ) ; return ; }
}
试题 F: 小球称重
思路:
本题主要考虑次品比较轻,所以在小于的那部分,其次然后后续根据大于和等于的情况,排除掉不可能的,因为TreeSet可以做到有序,查找和删除可以在log范围内进行,还要考虑一种特别特殊的情况,就是所有都是等于,说明次品在剩下的里面,所以就是n减去出现过的
参考代码:
import java. util. * ;
public class Main { public static void main ( String [ ] args) { Scanner in = new Scanner ( System . in) ; int n, m; n = in. nextInt ( ) ; m = in. nextInt ( ) ; TreeSet < Integer > s= new TreeSet < > ( ) ; TreeSet < Integer > s1= new TreeSet < > ( ) ; int f= 0 ; while ( m-- > 0 ) { int k = in. nextInt ( ) ; int l[ ] = new int [ k] ; int r[ ] = new int [ k] ; for ( int i= 0 ; i< k; i++ ) { l[ i] = in. nextInt ( ) ; s1. add ( l[ i] ) ; } for ( int i= 0 ; i< k; i++ ) { r[ i] = in. nextInt ( ) ; s1. add ( r[ i] ) ; } String re= in. next ( ) ; if ( re. equals ( "<" ) ) { for ( int i= 0 ; i< k; i++ ) { s. add ( l[ i] ) ; } for ( int i= 0 ; i< k; i++ ) { s. remove ( r[ i] ) ; } f= 1 ; } else if ( re. equals ( ">" ) ) { for ( int i= 0 ; i< k; i++ ) { s. remove ( l[ i] ) ; } for ( int i= 0 ; i< k; i++ ) { s. add ( r[ i] ) ; } f= 1 ; } else if ( re. equals ( "=" ) ) { for ( int i= 0 ; i< k; i++ ) { s. remove ( l[ i] ) ; } for ( int i= 0 ; i< k; i++ ) { s. remove ( r[ i] ) ; } } } if ( f== 0 ) { System . out. println ( n- s1. size ( ) ) ; return ; } System . out. println ( s. size ( ) ) ; return ; }
}
试题 G: 背包与魔法
思路:
可以参考01背包的思路,加一维判断是否使用了这个魔法
参考代码:
import java. util. * ;
public class Main { static int W [ ] = new int [ 2010 ] ; static int V [ ] = new int [ 2010 ] ; static int dp[ ] [ ] = new int [ 10010 ] [ 2 ] ; public static void main ( String [ ] args) { Scanner in= new Scanner ( System . in) ; int N , M , K ; N = in. nextInt ( ) ; M = in. nextInt ( ) ; K = in. nextInt ( ) ; for ( int i= 1 ; i<= N ; i++ ) { W [ i] = in. nextInt ( ) ; V [ i] = in. nextInt ( ) ; } for ( int i= 1 ; i<= N ; i++ ) { for ( int j= M ; j>= W [ i] ; j-- ) { dp[ j] [ 0 ] = Math . max ( dp[ j- W [ i] ] [ 0 ] + V [ i] , dp[ j] [ 0 ] ) ; if ( j- K - W [ i] >= 0 ) { dp[ j] [ 1 ] = Math . max ( dp[ j- W [ i] - K ] [ 0 ] + 2 * V [ i] , dp[ j] [ 1 ] ) ; dp[ j] [ 1 ] = Math . max ( dp[ j- W [ i] ] [ 1 ] + V [ i] , dp[ j] [ 1 ] ) ; } } } int ans= Math . max ( dp[ M ] [ 0 ] , dp[ M ] [ 1 ] ) ; System . out. println ( ans) ; return ; }
}
试题H:修路
思路:
将各个顶点分为3类,第一类左上角的点,标记为0,a的为1到n,b的为m+(1到n),然后将其建边,主要是一侧的相邻之间进行建边,相对的可以任意两两之间建边,然后跑最小生成树,得到结果
参考代码:
import java. util. * ;
public class Main { static Scanner cin= new Scanner ( System . in) ; static class node implements Comparable < node> { double val; int x; int y; @Override public int compareTo ( node o) { if ( this . val> o. val) { return 1 ; } else { return - 1 ; } } } static node p[ ] = new node[ 5000005 ] ; static int a[ ] = new int [ 2005 ] ; static int b[ ] = new int [ 2005 ] ; static int fa[ ] = new int [ 5000005 ] ; static int find ( int x) { if ( x== fa[ x] ) return x; else { return fa[ x] = find ( fa[ x] ) ; } } static void Merge ( int x, int y) { int xx= find ( x) ; int yy= find ( y) ; if ( xx!= yy) { fa[ xx] = yy; } } public static void main ( String [ ] args) { Scanner cin = new Scanner ( System . in) ; int n, m, d; n= cin. nextInt ( ) ; m= cin. nextInt ( ) ; d= cin. nextInt ( ) ; for ( int i= 1 ; i<= n; i++ ) { a[ i] = cin. nextInt ( ) ; } for ( int i= 1 ; i<= m; i++ ) { b[ i] = cin. nextInt ( ) ; } for ( int i= 0 ; i<= n* m+ n+ m; i++ ) { fa[ i] = i; } Arrays . sort ( a, 1 , n+ 1 ) ; Arrays . sort ( b, 1 , m+ 1 ) ; int cc= 0 ; p[ cc] = new node ( ) ; p[ cc] . val= ( double ) ( a[ 1 ] ) ; p[ cc] . x= 0 ; p[ cc] . y= 1 ; cc++ ; p[ cc] = new node ( ) ; p[ cc] . val= ( double ) ( Math . sqrt ( ( double ) ( b[ 1 ] * b[ 1 ] + d* d) ) ) ; p[ cc] . x= 0 ; p[ cc] . y= n+ 1 ; cc++ ; for ( int i= 2 ; i<= n; i++ ) { p[ cc] = new node ( ) ; p[ cc] . val= ( double ) ( a[ i] - a[ i- 1 ] ) ; p[ cc] . x= i- 1 ; p[ cc] . y= i; cc++ ; } for ( int i= 2 ; i<= m; i++ ) { p[ cc] = new node ( ) ; p[ cc] . val= ( double ) ( b[ i] - b[ i- 1 ] ) ; p[ cc] . x= i- 1 + n; p[ cc] . y= i+ n; cc++ ; } for ( int i= 1 ; i<= n; i++ ) { for ( int j= 1 ; j<= m; j++ ) { p[ cc] = new node ( ) ; p[ cc] . val= ( double ) ( Math . abs ( a[ i] - b[ j] ) * Math . abs ( a[ i] - b[ j] ) + d* d) ; p[ cc] . x= i; p[ cc] . y= j+ n; cc++ ; } } Arrays . sort ( p, 0 , cc) ; double ans= 0 ; int cnt= 0 ; for ( int i= 0 ; i< cc; i++ ) { if ( find ( p[ i] . x) != find ( p[ i] . y) ) { Merge ( p[ i] . x, p[ i] . y) ; ans+= p[ i] . val; cnt++ ; } if ( cnt== n+ m) { break ; } } System . out. printf ( "%.2f\n" , ans) ; return ; } }
试题I:围栏
计算几何不咋会(弱项)
试题J: 好数之和
思路:
把其他数位进行枚举,然后将其2022插入进去进行判断即可,kkkk枚举的是插入位置,其他是代表其他几位上的数
参考代码:
import java. util. * ;
public class Main { static Scanner cin= new Scanner ( System . in) ; public static void main ( String [ ] args) { int L , R ; L = cin. nextInt ( ) ; R = cin. nextInt ( ) ; long res = 0 ; for ( int kkkk = 0 ; kkkk < 6 ; kkkk++ ) { for ( int i = 0 ; i <= 9 ; i++ ) { for ( int j = 0 ; j <= 9 ; j++ ) { for ( int k = 0 ; k <= 9 ; k++ ) { for ( int kk = 0 ; kk <= 9 ; kk++ ) { for ( int kkk = 0 ; kkk <= 9 ; kkk++ ) { if ( kkkk == 0 ) { int ans = 0 ; ans = ans * 10 + i; ans = ans * 10 + j; ans = ans * 10 + k; ans = ans * 10 + kk; ans = ans * 10 + kkk; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } if ( ans >= L && ans <= R ) { res += ans; } } if ( kkkk == 1 ) { int ans = 0 ; ans = ans * 10 + i; ans = ans * 10 + j; ans = ans * 10 + k; ans = ans * 10 + kk; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } ans = ans * 10 + kkk; if ( ans >= L && ans <= R ) { res += ans; } } if ( kkkk == 2 ) { int ans = 0 ; ans = ans * 10 + i; ans = ans * 10 + j; ans = ans * 10 + k; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } ans = ans * 10 + kk; ans = ans * 10 + kkk; if ( ans >= L && ans <= R ) { res += ans; } } if ( kkkk == 3 ) { int ans = 0 ; ans = ans * 10 + i; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } ans = ans * 10 + k; ans = ans * 10 + kk; ans = ans * 10 + kkk; if ( ans >= L && ans <= R ) { res += ans; } } if ( kkkk == 4 ) { int ans = 0 ; ans = ans * 10 + i; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } ans = ans * 10 + j; ans = ans * 10 + k; ans = ans * 10 + kk; ans = ans * 10 + kkk; if ( ans >= L && ans <= R ) { res += ans; } } if ( kkkk == 5 ) { int ans = 0 ; int a[ ] = { 2 , 0 , 2 , 2 } ; for ( int jj = 0 ; jj < 4 ; jj++ ) { ans = ans * 10 + a[ jj] ; } ans = ans * 10 + i; ans = ans * 10 + j; ans = ans * 10 + k; ans = ans * 10 + kk; ans = ans * 10 + kkk; if ( ans >= L && ans <= R ) { res += ans; } } } } } } } } System . out. println ( res) ; return ; } }