目录
一、金币
原题链接
解析:
这题怎么说呢
第一天:1枚金币
第二天,第三天:2,枚金币
第四、五、六天:3枚金币;
那么每一个连续的天数内可以获得总金币数为:i^2;
第一个连续1天,获得1金币;
第二个连续2天,获得4金币;
第三个连续3天,获得9金币;
第n个连续n天,获得n*n金币;
然后你只需要判断每次的剩余天数和n的关系即可
代码如下:
代码:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
long s=0;
for(int i=1;;i++){
if(n>=i){
s+=i*i;
n-=i;
}else{
s+=i*n;
System.out.println(s);
return;
}
}
}
}
二、优秀的拆分
原题链接
解析:
这题两种解题方案:
方案一:判断原数是否为偶数,如果为奇数,直接输出-1;
为偶数,将该数变成2进制表达式;存于字符串中,进行每一位是否为1判断;
例如:100—>1100100;长度为7;第一位1位于0号位
所以第一个输出: 2的7-0-1次方,即2的6次方=64;
7:长度;0:所在位置;1:二进制从0次开始计算,减去;
同理;第二个1:2的7-1-1次=32;
第三个1:2的7-4-1次=4;相加=100;
方案二:判断原数是否为偶数,如果为奇数,直接输出-1;
为偶数,每一次判断这个数可以到达的最大的2的幂次数是多少,然后减去对应数,依次到为0;
代码如下:
代码:
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int j=1;
if(n%2==1){
System.out.println(-1);
}else{
while(n>0){
if(Math.pow(2,j)<=n&&Math.pow(2,j+1)>n){
System.out.print((int)Math.pow(2,j)+" ");
n-=Math.pow(2,j);
j=1;
}else{
j++;
}
}
}
}
}
三、穿越雷区
原题链接
解析:
这题能就是一个普通的bfs进阶问题,把原本的可以向上下左右四个方向移动变成了只能向与当前所在位置不同的值移动,所以,我们在设置的时候,可以把“-”电极设置为-1,“+”电极设置为-2,然后每次走和当前位置值不同我位置即可;代码如下:
(如果看不懂可以随时问,因为我也是bfs新学,在这里讲可能不太清楚)
代码:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 穿越雷区 {
static Scanner sc=new Scanner(System.in);
static int n;
static int [][]arr;
static int [][]brr;
static int sx,sy,ex,ey;
public static void main(String[] args) throws Exception{
init();
bfs();
}
static void init() throws Exception{
n=sc.nextInt();
arr=new int[n][n];
brr=new int[n][n];
for (int j=0;j<n;j++) {
for (int i = 0; i < n; i++) {//设置好位置
String ss=sc.next();
if (ss.charAt(0) == '-')
arr[j][i] = -1;
if (ss.charAt(0) == '+')
arr[j][i] = -2;
if (ss.charAt(0)=='A'){
sx=j;
sy=i;
}
if (ss.charAt(0)=='B'){
ex=j;
ey=i;
}
}
}
}
static void bfs(){
Queue<Integer> qx=new LinkedList<>();
Queue<Integer> qy=new LinkedList<>();
qx.add(sx);//加入队列
qy.add(sy);
int xa,ya;
brr[sx][sy]=0;//初始点
while (!qx.isEmpty()){
int x= qx.poll();//出队列
int y=qy.poll();
for (int i=-1;i<2;i+=2){
xa=x+i;
if (xa==ex&&y==ey){//走到了B点
System.out.println(brr[x][y]+1);//最后一次移动的步数
return;
}
if (xa>=0&&y>=0&&xa<n&&y<n&&pd(xa,y,x)){//满足条件加入队列
qx.add(xa);
qy.add(y);
brr[xa][y]=brr[x][y]+1;//步数加1
}
}
for (int i=-1;i<2;i+=2){//上同
ya=y+i;
if (x==ex&&ya==ey){
System.out.println(brr[x][y]+1);
return;
}
if (x>=0&&ya>=0&&x<n&&ya<n&&pd2(x,y,ya)){
qx.add(x);
qy.add(ya);
brr[x][ya]=brr[x][y]+1;
}
}
}
System.out.println(-1);
}
static boolean pd(int a,int b,int c){
return (arr[c][b] == 0 || arr[a][b] != arr[c][b]) && brr[a][b] == 0;
}//判断是否可以往该位置走
static boolean pd2(int a,int b,int c){
return (arr[a][b] == 0 || arr[a][c] != arr[a][b]) && brr[a][c] == 0;
}
}
四、蓝肽子序列
原题链接
解析:
这个子序列问题是小怂今天才刚学会的内容,有兴趣可以看看下面的视频讲解,我觉得讲的挺好的,而且还带有其他的动态规划讲解:B站视频
代码:
import java.util.Scanner;
public class 蓝肽子序列 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String sa=sc.next();
String sb=sc.next();
String []arr=new String[1000];
String []brr=new String[1000];
String a="",b="";
int k=0,y=0;
for (int i=0;i<sa.length();i++){
a+=sa.substring(i,i+1);
if (i+1==sa.length()||sa.charAt(i+1)>='A'&&sa.charAt(i+1)<='Z'){
arr[k]=a;
a="";
k++;
}
}
for (int i=0;i<sb.length();i++){
b+=sb.substring(i,i+1);
if (i+1==sb.length()||sb.charAt(i+1)>='A'&&sb.charAt(i+1)<='Z'){
brr[y]=b;
b="";
y++;
}
}
int [][]dp=new int[y+1][k+1];
for (int i=1;i<y+1;i++){
for (int j=1;j<k+1;j++){
if (arr[j-1].equals(brr[i-1])){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
System.out.println(dp[y][k]);
}
}