每日一题 Day18
题目:HJ37?统计每个月兔子的总数
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){//多组输入
int m=sc.nextInt();
System.out.println(num(m));
}
}
public static int num(int m){
if(m<=2){
return 1;
}
return num(m-1)+num(m-2);
}
}
题目:HJ71?字符串通配符
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNextLine()){
String t=sc.nextLine();//通配符字符串
String s=sc.nextLine();//字符串
System.out.println(match(t,s));
}
}
public static boolean match(String t,String s){
//因为要一个字符一个字符匹配,所以先拆成一个个字符放到数组中
char[] ct=t.toCharArray();
char[] cs=s.toCharArray();
int lt=ct.length;
int ls=cs .length;
boolean[][] dp=new boolean[ls+1][lt+1];//长:ls 宽:lt
dp[0][0]=true;//base case
for(int i=0;i<=ls;i++){//i用来遍历字符串数组
for(int j=1;j<=lt;j++){//j用来遍历通配符数组
if(ct[j-1]=='*'){//当通配符时*时(要单独判断,因为*可以匹配多个字符)
if(i==0){此时没有字符串与*匹配
dp[i][j]=dp[i ][j-1];//此时前一个是啥就是啥
}else{
if(cs[i-1]=='.'||cs[i-1]>='A'&&cs[i-1]<='Z'
||cs[i-1]>='a'&&cs[i-1]<='z'
||cs[i-1]>='0'&&cs[i-1]<='9'){
//如果截止到*的通配符和当前要匹配字符的前一个字符匹配成功,则为true(此时*匹配多个字符)
//如果*之前的通配符和要匹配字符匹配成功,则也为true(此时*匹配一个字符)
dp[i][j]=dp[i-1][j]||dp[i][j-1];
}
}
}else{//当通配符不是*时
if(i>0&&defs(ct[j-1],cs[i-1])){//defs方法,用来看通配符表达式和字符串是不是相等
//如果当前字符匹配成功,要看一下前面的字符是否匹配成功,都成功才成功
dp[i][j]=dp[i-1][j-1];
}
}
}
}
return dp[ls][lt];
}
public static boolean defs(char t,char s){//判断字符是否匹配
if(t=='?') return true;
if(t>='a'&&t<='z'){
t=(char)(t-'a'+'A');//把小写字母转换成大写字母
}
if(s>='a'&&s<='z'){
s=(char)(s-'a'+'A');
}
return s==t;
}
}
?每日一题 Day19
?题目:36889-查找两个字符串a,b中的最长公共子串
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
String str1=sc.nextLine();
String str2=sc.nextLine();
if(str1.length()<str2.length()){
System.out.println(getMaxSubstr(str1,str2));
}else{
System.out.println(getMaxSubstr(str2,str1));
}
}
}
//假设str1长度短
public static String getMaxSubstr(String str1,String str2){
char[]arr1=str1.toCharArray();
char[]arr2=str2.toCharArray();
int len1=arr1.length;
int len2=arr2.length;
//最长子串的起始位置
int start=0;
//最长的子串长度
int maxLen=0;
//多增加一行一列,作为辅助状态
int[][] maxSubLen=new int[len1+1][len2+1];
//以str1的第i个字符结尾和以str2的第j个字符结尾的最长公共字串的长度
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
//如果第i个字符和第j个字符相等,则进行累加
if(arr1[i-1]==arr2[j-1]){
maxSubLen[i][j]=maxSubLen[i-1][j-1]+1;
//更新
if(maxLen<maxSubLen[i][j]){
maxLen=maxSubLen[i][j];
start=i-maxLen;
}
}
}
}
return str1.substring(start,start+maxLen);
}
}
?题目:36846-汽水瓶
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int num=sc.nextInt();
if(getNum(num)!=0){
System.out.println(getNum(num));
}
}
}
public static int getNum(int num){//num为空瓶的个数
//汽水的个数
int sum=0;
while(num>1){
//兑换的汽水的个数num/3
sum+=num/3;
//剩余的空瓶子
num=num/3+num%3;
if(num==2){
//借一瓶
sum++;
break;
}
}
return sum;
}
}
每日一题 Day20
题目:36899-公共字串计算
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
String str1=sc.nextLine();
String str2=sc.nextLine();
System.out.println(getMaxLen(str1,str2));
}
public static int getMaxLen(String str1,String str2){
char[]arr1=str1.toCharArray();
char[]arr2=str2.toCharArray();
int len1=arr1.length;
int len2=arr2.length;
int maxLen=0;
int[][]maxSubLen=new int[len1+1][len2+1];
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(arr1[i-1]==arr2[j-1]){
//状态转移方程
maxSubLen[i][j]=maxSubLen[i-1][j-1]+1;
}
//更新最大值
if(maxLen<maxSubLen[i][j]){
maxLen=maxSubLen[i][j];
}
}
}
return maxLen;
}
}
题目:36836-字符串反转
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
char[]arr=str.toCharArray();
int len=arr.length;
int i=0;
int j=len-1;
while(i<j){
char tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
i++;
j--;
}
String s=new String(arr);
System.out.println(s);
}
}
每日一题 Day21
题目:MP3光标位置
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
String numStr=sc.nextLine();
String orderStr=sc.nextLine();
mouseMove(numStr,orderStr);
}
public static void mouseMove(String numStr,String orderStr){
//歌曲数量
int n=Integer.parseInt(numStr);
//指令数组:UD
char[] order=orderStr.toCharArray();
//当前鼠标所在的位置
int mouse=1;//光标初始的位置为第1首歌
//显示列表所在的起始位置
int first=1;
//指令处理
//歌曲数量n<=4时
if(n<=4){
for(int i=0;i<order.length;i++){
//光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲
if(mouse==1&&order[i]=='U'){
mouse=n;
}
//光标在最后一首歌曲时,按Down键光标挪到第一首歌曲
else if(mouse==n&&order[i]=='D'){
mouse=1;
}
//其他情况下用户按Up键,光标挪到上一首歌曲
else if(order[i]=='U'){
mouse--;
}
//用户按Down键,光标挪到下一首歌曲
else if(order[i]=='D'){
mouse++;
}
}
//输出
//打印当前的显示列表
for(int i=1;i<n;i++){
System.out.print(i+" ");
}
System.out.println(n);
//打印当前歌曲
System.out.println(mouse);
}
//歌曲数量n>4时
else{
for(int i=0;i<order.length;i++){
//屏幕显示的是第一页(即显示第1 – 4首)时,
//光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),
//同时光标放到最后一首歌上。
if(first==1&&mouse==1&&order[i]=='U'){
//最后一页的起始位置为歌曲数-3
first=n-3;
mouse=n;
}
//屏幕显示最后一页时,光标在最后一首歌曲上,
//用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
else if(first==n-3&&mouse==n&&order[i]=='D'){
first=1;
mouse=1;
}
//屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,
//用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲
else if(first!=1&&mouse==first&&order[i]=='U'){
first--;
mouse--;
}
//光标当前屏幕的最后一首歌时的Down键处理也类似
else if(first!=n-3&&mouse==first+3&&order[i]=='D'){
first++;
mouse++;
}
//其他情况,不用翻页,只是挪动光标就行。
else if(order[i]=='U'){
mouse--;
}
else if(order[i]=='D'){
mouse++;
}
}
//输出
//打印当前的显示列表
for(int i=first;i<first+3;i++){
System.out.print(i+" ");
}
System.out.println(first+3);
//打印当前歌曲
System.out.println(mouse);
}
}
}
题目:洗牌
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
int groups=sc.nextInt();
for(int i=0;i<groups;i++){
//读入每组数据
int n=sc.nextInt();
int k=sc.nextInt();
int[] cards=new int[2*n];
for(int j=0;j<2*n;j++){
cards[j]=sc.nextInt();
}
//洗牌
playCard(cards,n,k);
}
}
//n为牌数一半,k为洗牌次数
public static void playCard(int[] cards,int n,int k){
//编号为i是牌,最后放到2*i位置
//编号为i+n的牌最后放到2*i+1位置
for(int i=0;i<k;i++){
//一次洗牌的过程
int [] newCards=new int [cards.length];
for(int j=0;j<n;j++){
//遍历编号为0~n-1的牌
newCards[2*j]=cards[j];
newCards[2*j+1]=cards[j+n];
}
cards=newCards;
}
//洗完之后从上往下打印
printCard(cards);
}
public static void printCard(int[]cards){
for(int i=0;i<cards.length-1;i++){
System.out.print(cards[i]+" ");
}
System.out.println(cards[cards.length-1]);
}
}
每日一题 Day22
题目:找出字符串中第一个只出现一次的字符
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
String str=sc.nextLine();
find(str);
}
}
public static void find(String str){
char[] arr=str.toCharArray();
int[] check=new int[128];
boolean flg=false;
for(int i=0;i<arr.length;i++){
check[arr[i]]++;
}
for(int i=0;i<arr.length;i++){
if(check[arr[i]]==1){
System.out.println(arr[i]);
flg=true;
break;
}
}
if(flg==false){
System.out.println(-1);
}
}
}
题目:小易的升级之路
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();//怪物的数量
int x=sc.nextInt();//小易的初始能力值
int[] nums=new int[n];//怪物的防御力
for(int i=0;i<n;i++){
nums[i]=sc.nextInt();
if(nums[i]<=x){
x+=nums[i];
}
else{
x+=gcd(x,nums[i]);
}
}
System.out.println(x);
}
}
public static int gcd(int a,int b){//求最大公约数
int c;
while((c=a%b)!=0){
a=b;
b=c;
}
return b;
}
}
每日一题 Day23
题目:计算字符串的编辑距离
import java.util.*;
public class Main{
public static void main(String[]args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
String str1=sc.nextLine();
String str2=sc.nextLine();
System.out.println(getDistance(str1,str2));
}
}
public static int getDistance(String str1,String str2){
char[] wd1=str1.toCharArray();
char[] wd2=str2.toCharArray();
int len1=wd1.length;
int len2=wd2.length;
//编辑距离矩阵
int[][] dist=new int[len1+1][len2+1];
//初始状态:
//从i个字符变成0个字符,需要删除i个字符:F[i,0]=i
//从0个字符变成j个字符,需要插入j个字符:F[0,j]=j
for(int i=0;i<=len1;i++){
dist[i][0]=i;
}
for(int j=0;j<=len2;j++){
dist[0][j]=j;
}
//状态转移
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
//首先求出插入和删除的最小值
dist[i][j]=Math.min(dist[i-1][j],dist[i][j-1])+1;
//再和替换作比较
if(wd1[i-1]==wd2[j-1]){//此时不需要替换
dist[i][j]=Math.min(dist[i][j],dist[i-1][j-1]);
}else{//此时需要替换
dist[i][j]=Math.min(dist[i][j],dist[i-1][j-1]+1);
}
}
}
return dist[len1][len2];
}
}
题目:微信红包
import java.util.*;
public class Gift {
public int getValue(int[] gifts, int n) {
Arrays.sort(gifts);
int mid=gifts[n/2];
int count=0;
//统计中间位置数据出现的次数
for(int g:gifts){
if(g==mid){
count++;
}
}
if(count>n/2){
return mid;
}else{
return 0;
}
}
}
public class Gift {
public int getValue(int[] gifts, int n) {
// write code here
Map<Integer,Integer>map=new HashMap<>();
for(int g:gifts){
if(map.containsKey(g)){
map.put(g,map.get(g)+1);
}else{
map.put(g,1);
}
if(map.get(g)>=n/2){
return g;
}
}
return 0;
}
}
每日一题 Day24
题目:迷宫问题
import java.util.*;
import java.io.*;
class Node{
int x;
int y;
public Node(int x,int y){
this.x=x;
this.y=y;
}
}
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int row = sc.nextInt();
int col = sc.nextInt();
//创建迷宫矩阵
int[][] mat = new int[row][col];
//读入迷宫数据
for(int i = 0; i < row; i++) {
for(int j = 0; j < col; j++) {
mat[i][j] = sc.nextInt();
}
}
//搜索最短路径
ArrayList<Node> path = new ArrayList<>();
ArrayList<Node> minPath = new ArrayList<>();
int[][] book = new int[row][col];
getMinPath(mat, row, col, 0, 0, book, path, minPath);
//打印最短路径
for(Node n : minPath) {
System.out.println("(" + n.x + "," + n.y + ")");
}
}
}
//mat表示迷宫矩阵;x,y为当前位置
//book为标记矩阵,标记当前位置是否走过
//path保存路径中的每个位置
//minpath保存最小路径
public static void getMinPath(int[][] mat,int row,int col,
int x,int y,int[][]book,ArrayList<Node>path,ArrayList<Node>minPath){
//判断(x,y)是否越界,是否走过,是否有障碍
if(x<0||x>=row||y<0||y>=col
||book[x][y]==1||mat[x][y]==1){
return;
}
//把当前位置存入路径中
path.add(new Node(x,y));
//标记当前位置
book[x][y]=1;
//判断当前位置是否为目的位置
if(x==row-1&&y==col-1){
//如果当前位置为目的位置,证明找到了一条路径
//此时判断当前路径是否为最短路径
if(minPath.isEmpty()||path.size()<minPath.size()){
//更新更短路径
minPath.clear();
for(Node n:path){
minPath.add(n);
}
}
}
//继续搜索(x,y)的上下左右四个方向
getMinPath(mat,row,col,x+1,y,book,path,minPath);
getMinPath(mat,row,col,x-1,y,book,path,minPath);
getMinPath(mat,row,col,x,y-1,book,path,minPath);
getMinPath(mat,row,col,x,y+1,book,path,minPath);
//把当前位置从路径中删掉,寻找新的路径
path.remove(path.size()-1);
book[x][y]=0;
}
}
题目:年终奖
import java.util.*;
public class Bonus {
public int getMost(int[][] board) {
int row=board.length;
int col=board[0].length;
//处理第一行:只能从左向右走
for(int i=1;i<col;i++){
board[0][i]+=board[0][i-1];
}
//处理第一列:只能从上向下走
for(int i=1;i<row;i++){
board[i][0]+=board[i-1][0];
}
//剩余位置
for(int i=1;i<row;i++){
for(int j=1;j<col;j++){
board[i][j]+=Math.max(board[i-1][j],board[i][j-1]);
}
}
return board[row-1][col-1];
}
}
|