做题——打卡006

第一题:八皇后改

问题描述

  规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大。

输入格式

  一个8*8的棋盘。

输出格式

  所能得到的最大数字和

样例输入

1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
48 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64

样例输出

260

数据规模和约定

  棋盘上的数字范围0~99

import java.util.Scanner;

public class Main {

    private static int maxSum; // 最大数字和

    public static void main(String[] args) {
        int[][] board = new int[8][8];
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                board[i][j] = sc.nextInt();
            }
        }

        backtrack(board, 0, new int[8]);
        System.out.println(maxSum);
    }

    /**
     * 回溯函数,按照行进行选择
     *
     * @param board 棋盘
     * @param row   当前处理的行号
     * @param cols  记录每行皇后所在的列号
     */
    private static void backtrack(int[][] board, int row, int[] cols) {
        if (row == 8) { // 找到一组解,比较更新数字和最大值maxSum
            int sum = 0;
            for (int i = 0; i < cols.length; i++) {
                sum += board[i][cols[i]];
            }
            maxSum = Math.max(maxSum, sum);
            return;
        }
        for (int col = 0; col < 8; col++) { // 遍历每个格子(当前行的每一列)
            if (isLegal(cols, row, col)) { // 判断该位置是否可以放置皇后
                cols[row] = col;
                backtrack(board, row + 1, cols); // 向下一行进行选择
                cols[row] = -1;
            }
        }
    }

    /**
     * 判断该位置是否可以放置皇后
     *
     * @param cols 数组,indexes of cols
     * @param row  当前要放置的行号
     * @param col  当前要放置的列号
     */
    private static boolean isLegal(int[] cols, int row, int col) {
        for (int i = 0; i < row; i++) { // 遍历之前所有已经放置的行
            if (cols[i] == col || Math.abs(i - row) == Math.abs(cols[i] - col)) { // 判断当前位置是否合法(列不能相同,斜线上也不能有重复)
                return false;
            }
        }
        return true; // 表示当前位置合法
    }
}

第二题:线段长度

问题描述

  给出n个线段以及它们的左端点和右端点。我们要求得到这些线段覆盖部分的长度。如线段[1,2]和[2,3]覆盖了数轴上1到3这个部分,所以它们覆盖的长度就是2。

输入格式

  第一行一个数n表示有n条线段,之后的n行每行两个整数表示每个线段的左端点和右端点。

输出格式

  一个数表示覆盖部分的长度。

样例输入

3
1 2
2 3
4 5

样例输出

3

数据规模和约定

  0<n<=1000, 答案不超过32位整数。


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] segments = new int[n][2];
        for (int i = 0; i < n; i++) {
            segments[i][0] = sc.nextInt();
            segments[i][1] = sc.nextInt();
        }
        Arrays.sort(segments, (a, b) -> a[0] - b[0]);
        int res = 0;
        int left = segments[0][0], right = segments[0][1];
        for (int i = 1; i < n; i++) {
            if (segments[i][0] <= right) { // 有重叠部分
                right = Math.max(right, segments[i][1]); // 扩展右端点
            } else { // 没有重叠部分
                res += right - left; // 更新覆盖长度
                left = segments[i][0]; // 更新左右端点
                right = segments[i][1];
            }
        }
        res += right - left; // 最后还要再更新一次覆盖长度
        System.out.println(res);
    }
}


思路:

先按照线段的左端点从小到大排序,然后从第二个线段开始遍历,如果当前线段与前一个线段有重叠,就更新右端点;否则就将前一个线段的覆盖长度加入结果中,并更新左右端点。最后还要再加上最后一个线段的覆盖长度。

时间复杂度:O(nlogn),其中n为线段数量。


第三题:luck

问题描述

  S国是一个爱好数字的国度,总有些人会夜以继日的数着数字以占卜凶吉,凡是数字在十进制表示之下有连续k个4或k个7相连则被认为是幸运的。他们看遍了1到n之间的所有数,想考一考你。因为他们预先知道答案,所以他们只需你告诉他们幸运的数字mod 109+7就行。

输入描述

  第一行一个数k。
  第二行一个数n。

输出描述

  一个数,如题所述。

样例输入

1
100

样例输出

36

数据规模和约定

  设t为n的位数
  20%的数据n<=106
  40%的数据n<=1018
  60%的数据t<=5000
  100%的数据1<=k<=t<=106


import java.util.*;

public class Main {
    static final int MOD = 1000000007;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int k = sc.nextInt(); //连续k个4或k个7
        long n = sc.nextLong(); //1到n之间的所有数

        long[][] dp = new long[(int) (n + 1)][k + 1]; //dp[i][j]表示数字i放置了j个'4'或'7'
        for (int i = 0; i <= k; i++) {
            dp[0][i] = 1; //数字0不放任何'4'或'7',只有一种情况
        }

        long res = 0;
        for (long i = 1; i <= n; i++) {
            res += dfs(dp, i, k); //计算当前数字在放置了k个'4'或'7'时的方案数,并累加到结果上
            res %= MOD;
        }

        System.out.println(res);
    }

    private static long dfs(long[][] dp, long num, int k) {
        if (num == 0) { //递归终止条件:数字为0,只有一种情况,即不放任何'4'或'7'
            return 1;
        }
        if (dp[(int) num][k] != 0) { //如果已经计算过此状态,则直接返回结果
            return dp[(int) num][k];
        }

        long tmpNum = num / 10;
        int lastDigit = (int) (num % 10);

        long res = 0;
        if (lastDigit == 4 || lastDigit == 7) { //如果当前数字的个位是'4'或'7',则递归计算上一位数字已经放置了k-1个'4'或'7'
            if (k > 0) {
                res += dfs(dp, tmpNum, k - 1);
                res %= MOD;
            }
        }

        res += dfs(dp, tmpNum, k); //递归计算上一位数字已经放置了k个'4'或'7'

        dp[(int) num][k] = res; //记录此状态的结果

        return res;
    }
}


该问题可以通过动态规划+递归来解决。设dp[i][j]表示数字i放置了j个'4'或'7'时的方案数。对于一个数字num,其包含的所有合法方案总数等于:在num%10为4或7的情况下,num/10放置了j-1个4或7的方案数 + num/10放置了j个4或7的方案数。

需要注意的是,在计算num%10为4/7时,需要判断j是否大于0,因为当j=0时表示不能再放置任何4或7。同时,为了避免重复计算,使用一个二维数组dp来存储已经计算过的状态结果。


第四题:最大区间和(最大子序列和问题)

问题描述

  给定n个数A1,A2,A3……An,求两个数l,r满足l<=r并最大化Al+A(l+1)+……Ar,输出这个最大值

输入格式

  第一行一个数n,接下来一行有n个用空格隔开的数,第i个数表示Ai

输出格式

  输出仅一行,即最大区间和

样例输入

4
-1 -2 -3 4

样例输出

4

数据规模和约定

  每个数绝对值不超过2^30;
  n<=1000000

package 备赛课.动态规划;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class 最大区间和  {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pr = new PrintWriter(System.out);
        int n = Integer.parseInt(br.readLine());
        String a[] = br.readLine().split(" ");

      long [] f = new long [n]; //存储以每个位置为结尾的最大子段和
        f[0] = Integer.parseInt(a[0]);
        for (int i = 1; i < n; i++) {
            f[i] = Math.max(f[i - 1] + Long.parseLong(a[i]), Long.parseLong(a[i]));
        }

      long  res = Long.MIN_VALUE;
        for (int i = 0; i < n; i++) { //找到所有f中的最大值
            res = Math.max(res, f[i]);
        }
        pr.println(res);
        pr.flush();
        pr.close();

    }

}

第五题:质因子个数

package 算法提高;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class 质因数个数 {
	static BufferedReader bu = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter pr = new PrintWriter(System.out);

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		long n = Long.parseLong(bu.readLine());
        long bak = n ,count=0,sum=1; 
		for(long i = 2 ; i*i<=n;i++) {
			if(bak%i==0) {
				count++;
				while(bak%i==0) {
					System.out.print(i+" ");
					bak/=i;
				}
			}
		}
		if(bak>1) {
			pr.println(++count);
			 pr.flush();
			return;
		}
	 pr.println(count);
	 pr.flush();
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Vue2来实现签到打卡功能,可以按照以下步骤进行: 1. 创建一个Vue2项目:首先,你需要创建一个Vue2项目并安装Vue CLI。可以使用以下命令创建一个新的Vue项目: ``` vue create sign-in-app ``` 然后根据指示选择自定义配置,并选择需要的特性。 2. 创建组件:在Vue项目中,你可以创建一个名为`SignIn`的组件,用于展示签到打卡的界面。可以使用以下命令创建一个新的组件: ``` vue generate component SignIn ``` 然后在`SignIn.vue`文件中编写签到打卡的界面布局和交互逻辑。 3. 定义数据和方法:在`SignIn.vue`组件中,你可以定义需要用到的数据和方法。例如,可以定义一个变量`signedIn`来表示用户是否已经签到,以及一个方法`signIn`来处理用户点击签到按钮的逻辑。 4. 绑定数据和事件:在组件的模板中,你需要绑定数据和事件来实现签到打卡功能。例如,你可以使用`v-if`指令根据`signedIn`变量的值显示不同的界面内容,使用`v-on:click`指令绑定`signIn`方法到签到按钮上。 5. 调用API:在`signIn`方法中,你可以调用后端提供的API来实现真正的签到功能。你可以使用Vue的内置`axios`库或其他HTTP库发起HTTP请求。 6. 样式设计:根据你的需求,你可以使用CSS或其他样式库为签到打卡界面添加样式。 这只是一个简单的指导步骤,实际实现签到打卡功能需要根据具体需求进行详细设计和开发。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值