第十四届蓝桥杯冲刺打卡day13

1、特殊日期

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class 特殊日期 {
    public static void main(String[] args) {
       int res = 0;
       for(int i =1900;i<=9999;i++){
         int sumYear = sum(i);
         int[]month ={0,31,28,31,30,31,30,31,31,30,31,30,31};
            if(i%400==0||i%4==0&&i%100!=0){
              month[2]=29;
            }
            for(int j = 1;j<=12;j++){
              int sumMonth = sum(j);
               for(int d=1;d<=month[j];d++){
                 int sumDay = sum(d);
                 if(sumYear==sumMonth+sumDay){
                   res++;
                 }
               }
            }
       }
       System.out.println(res);
    }
    static int sum(int w){
      int m = 0;
      while(w>0){
        m+=w%10;
        w/=10;
      }
      return m;
    }
}

2、重合次数

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        int h = 6;
        int m = 13;
        int s = 22;
        int res = 0;
        while(true){
          if(h==14&&m==36&&s==20){
            break;
          }
          if(m==s){
            res++;
          }
          if(s>60){
            m+=1;
            s=1;
          }
          if(m>60){
            h+=1;
            m=1;
          }
          s++;

        }
        System.out.println(res);
    }
}

3、左移右移

import java.util.Arrays;
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class 左移右移 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
       int m = sc.nextInt();
       int [][]nums = new int[n+1][2];//用二维数组保存原来的数组和变化状态
       for(int i = 1;i<=n;i++){
         nums[i][0] = i;
       }
       int l = 0;
       int r = n;
       while(m-->0){
        String dir = sc.next();
        int num = sc.nextInt();
        if(dir.equals("L")){
          nums[num][1]=--l;//将对应数的状态数组进行状态变化
        }
        else{
          nums[num][1]=++r;//变化
        } 
       }
       Arrays.sort(nums, 1, n + 1, (o1, o2) ->{//根据状态变化进行数组的排序,例中3变为0,2变为-1,1变为6
    	   return Integer.compare(o1[1],o2[1]);
       });
       for(int i=1;i<=n;i++) {
    	   System.out.printf("%d ",nums[i][0]);
       }
    }
}

4、思路都在代码里

问题描述

小蓝有一个长度为 n 的数组 =(1,2,⋯,)A=(a1​,a2​,⋯,an​), 数组的子数组被定义为从 原数组中选出连续的一个或多个元素组成的数组。数组的最大公约数指的是数 组中所有元素的最大公约数。如果最多更改数组中的一个元素之后, 数组的最 大公约数为 g, 那么称 g 为这个数组的近似 GCD。一个数组的近似 GCD 可能 有多种取值。

具体的, 判断 g 是否为一个子数组的近似 GCD 如下:

  1. 如果这个子数组的最大公约数就是 g, 那么说明 g 是其近似 GCD。

  2. 在修改这个子数组中的一个元素之后 (可以改成想要的任何值), 子数 组的最大公约数为 g, 那么说明 g 是这个子数组的近似 GCD。

小蓝想知道, 数组 A 有多少个长度大于等于 2 的子数组满足近似 GCD 的 值为 g 。

输入格式

输入的第一行包含两个整数 n,g, 用一个空格分隔, 分别表示数组 A 的长 度和 g 的值。

第二行包含 n 个整数 1,2,⋯,a1​,a2​,⋯,an​, 相邻两个整数之间用一个空格分隔。

输出格式

输出一行包含一个整数表示数组 A 有多少个长度大于等于 2 的子数组的近 似 GCD 的值为 g 。

样例输入

5 3
1 3 6 4 10

样例输出

5

样例说明

满足条件的子数组有 5 个:

[1,3][1,3] : 将 1 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。

[1,3,6][1,3,6] : 将 1 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。

[3,6]:这个子数组的最大公约数就是 3 , 满足条件。

[3,6,4][3,6,4] : 将 4 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。

[6,4][6,4] : 将 4 修改为 3 后, 这个子数组的最大公约数为 3 , 满足条件。

评测用例规模与约定

对于 20%20% 的评测用例, 2≤n≤102 ;

对于 40%40% 的评测用例, 2≤n≤103;

对于所有评测用例, 2≤n≤105,1≤g,ai​≤109 。

import java.util.*;
import java.math.*;
import java.io.*;

public class 近似GCD {

    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    
    static int N = (int)1e5 + 10, n, g;
    static int[] a = new int[N];

    public static void main(String[] args) throws Exception {
    	String[] s = in.readLine().split(" ");
    	n = Integer.parseInt(s[0]);//数组长度
    	g = Integer.parseInt(s[1]);//最大公约数
    	s = in.readLine().split(" ");//数组元素
    	for (int i = 1; i <= n; i++) {//对数组进行赋值,从下标1开始
    		a[i] = Integer.parseInt(s[i - 1]) % g == 0? 1: 0;//判断,将能够被g%尽的赋值为1,不能的即为0
    		a[i] += a[i - 1];//前缀和,前缀和的作用是计算每个区间有几个能把g%尽的数字
    	}
    	long ans = 0L;//个数
    	//双指针
    	int start = 0;//左指针,左端点,从0开始还有一个原因,区间长度不少于2,1到2应该用2-0来包含
    	for (int end = 2; end <= n; end++) {//因为区间长度最短不能少于2,所以右指针end从2开始
//这里的start+1<end(start+2<=end)是为了保证实际上左边与右边距离大于等于2,并且此区间只能最多一个不能被g%尽的,所以a[end]-a[start]+1相当于计算在start到end这段的数字在补上一个g后,能不能满足这个区间所有数字都能%g尽,所以要和长度end-start比较,小于的话那必然需要左边往后走了
    		while (start+1<end && a[end] - a[start] + 1 < end - start) {
    			start++;//尽量长的一段结束了,左指针开始往后移动,重新与end规划区间
    		}
    		//System.out.printf("end,start%d %d\n",end,start);
    		ans += end - start - 1;//因为每个需要补的区间都是需要补1个g,所以只需要用区间长度减去补的一个位置即可
    		//System.out.println(ans);
    	}
    	out.println(ans);
     
        out.flush();
        in.close();
    }  
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值