蓝桥2017JavaB题解

1、纸牌三角形
题目:A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。

思路:全排列问题

代码:

public class App2 {
  
       public static int res = 0;
   
       public static void f(int[] arr, int n) {
   
           if (n == arr.length) {
            System.out.println(arr[0]+" "+arr[1]+" "+arr[2]+" "+arr[3]+" "+arr[4]+" "+arr[5]+" "+
              arr[6]+" "+arr[7]+" "+arr[8]);
              if (arr[0] + arr[1] + arr[3] + arr[5] == arr[5] + arr[6] + arr[7] + arr[8]
                       && arr[5] + arr[6] + arr[7] + arr[8] == arr[0] + arr[2] + arr[4] + arr[8]) {
                  res += 1;
              }
              return;
          }
  
          for (int i = n; i < arr.length; i++) {
              int temp = arr[n];//交换位置
              arr[n] = arr[i];
              arr[i] = temp;
              f(arr, n + 1);
              temp = arr[n];//将arr[]恢复
              arr[n] = arr[i];
              arr[i] = temp;
              
          }
  
      }
  
      public static void main(String[] args) {
          int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
          f(arr, 0);
          System.out.println(res);
          System.out.println(res / 6);  // 答案: 144
      }
  
  }

2、取数位
题目:求1个整数的第k位数字有很多种方法。
以下的方法就是一种。

public class Main
{
 static int len(int x){
  if(x<10) return 1;
  return len(x/10)+1;
 }
 
 // 取x的第k位数字
 static int f(int x, int k){
  if(len(x)-k==0) return x%10;
  return ______________________;  //填空
 }
 
 public static void main(String[] args)
 {
  int x = 23513;
  //System.out.println(len(x));
  System.out.println(f(x,3));
 }
}

对于题目中的测试数据,应该打印5。
请仔细分析源码,并补充划线部分所缺少的代码

答案:f(x/10,k) ;
7、日期问题
题目:小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入

一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输入

输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入

02/03/04
样例输出

2002-03-04
2004-02-03
2004-03-02
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

代码:

public class App7 {
 public static String show(int a,int b,int c) {
  String x;
  String y;
  if(a>59)a=2000+a;
  else a=1900+a;
  if(b>12) {
   return "1";
  }else {
   if(b<10)x=0+""+b;
   else x=b+"";
  }
  if(c>31) {
   return"1";
  }else if(b==4||b==6||b==9||b==11) {
   if(c>30) {
    return "1";
   }
  }else if(b==2) {
   if(a%4==0) {
    if(c>29) {
     return "1";
    }
   }else {
    if(c>28) {
     return "1";
    }
   }
  }
  if(c>10) {
   y=c+"";
  }else {
   y=0+""+c;
  }
  return a+"-"+x+"-"+y;
 }
 public static void main(String[] args) {
  Scanner sc=new Scanner(System.in);
  String str=sc.next();
  String a=str.substring(0,2);
  String b=str.substring(3,5);
  String c=str.substring(6);
  int x=Integer.parseInt(a);
  int y=Integer.parseInt(b);
  int z=Integer.parseInt(c);
  String []str1=new String[6];
  String []str2=new String[6];
  str1[0]=show(x,y,z);
  str1[1]=show(x,z,y);
  str1[2]=show(y,x,z);
  str1[3]=show(y,z,x);
  str1[4]=show(z,x,y);
  str1[5]=show(z,y,x);
  for(int i=0;i<6;i++) {
   for(int j=0;j<6;j++) {  
    if(str1[i].equals(str1[j])&&i!=j)str1[j]="1";
   }
  }
  for(int i=0;i<6;i++) {
   if(str1[i]!="1") {
    System.out.println(str1[i]);
   }
  }
 }
}

10、k倍区间
题目:给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列Ai, Ai+1, … Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
输入

第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)
输出

输出一个整数,代表K倍区间的数目。
例如,
输入:
5 2
1
2
3
4
5
程序应该输出:
6
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

思路:前缀和,数学
代码:

import java.util.Scanner;
public class App10 {
 static int a[]=new int [100001];
 static int b[]=new int [100001];
 static int c[]=new int [100001];
 static Scanner sc=new Scanner(System.in);
 public static void main(String[] args) {
  int n=sc.nextInt();
  int k=sc.nextInt();
  a[0]=sc.nextInt();
  b[0]=a[0];
  for(int i=1;i<n;i++) {//计算前缀和
   a[i]=sc.nextInt();
   b[i]=b[i-1]+a[i];
   b[i]%=k;
  }
  for(int i=0;i<n;i++) {
   b[i]%=k;
   c[b[i]]++;
  }
  int ans=0;
  for(int i=0;i<k;i++) {//任意两个相同的数相减得到的取钱可以时K被区间
   ans+=c[i]*(c[i]-1)/2;
  }
  System.out.println(ans+c[0]);
 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值