JAVA B组参考代码
试题 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 ;
}
}