牛客练习赛13

练习题链接

A:幸运数字

出现4、或者出现7、(当中最大的那个、47什么的是不存在的、因为它就是由4、7组成的、)

import java.util.Scanner;

public class A {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.next();
        int a, b; //  a  存的是 4 出现的次数、  b 存的是 7出现的次数、、
        a = b = 0;
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == '4'){
                a++;
            }else if(s.charAt(i) == '7'){
                b++;
            }
        }
        
        if(a != 0 || b != 0){
            if(a >= b){
                System.out.println("4");
            }else{
                System.out.println("7");
            }
        }else{
            System.out.println("-1");
        }
        
    }
    
}
B:幸运数字Ⅱ

最左边、左右边、是两个界限、每次求的是当前边界、最l 是否是“幸运数字”、是的话、那直接取出来、然后下限++、 不是的话、向上找最近的“幸运数字”、然后这个区间的数的个数、乘以这个“幸运数字”、如此即可、(注意边界)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class B_ {
    static final int MAXN = 1000005;
    static long l , r;
    static int num;
    static long [] sum = new long [MAXN];
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        long ans = 0;
        in.nextToken(); l = (long)in.nval;
        in.nextToken(); r = (long)in.nval;
        Init();
        for(int i  = 1; i <= num; i++){
            if(sum[i] >= l && l <= r){
                if(sum[i] <= r){
                    ans += (sum[i] - l + 1) * sum[i]; // 找到当前最小的上界、、
                }else if(sum[i] >= r){  // 当前最小的幸运数字都大于上界、、
                    ans += (r - l + 1) * sum[i];
                }
                l = sum[i] + 1; // 下界变为这个幸运数字 + 1、、
            }
            if(l > r) break;
        }
        out.println(ans);
        out.flush();
    }
    
    
    private static void Init(){
        num = 2;
        sum[1] = 4; 
        sum[2] = 7;
        for(int i = 1; i <= 77777; i++){
            sum[++num] = sum[i] * 10 + 4;
            sum[++num] = sum[i] * 10 + 7;
        }
    }
}

C:幸运数字Ⅲ

我到现在也没有弄懂、题解如下:


代码:

import java.util.Scanner;

public class C {
    
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n ,k; // 数字的长度、 以及操作的次数、、
        n = input.nextInt();
        k = input.nextInt();
        String s = input.next();
        char [] c = s.toCharArray();

        for(int j = 0; j < n; j++){  // fuck  为什么会这个样子、、、
            for(int i = 1; i < k; i++){
                if(c[i - 1] == '4' && c[i] == '7'){
                    if((i & 1) == 1){ // 偶数 。那这数就是奇数、、
                        c[i] = '4';
                    }else{
                        c[i - 1] = '7';
                    }
                    break;
                }
            }
        }
        for(int i = 0; i < c.length; i++){
            System.out.print(c[i]);
        }
        System.out.println("");
    }
}

D:幸运数字Ⅳ

题解如下:


代码自己太弱、暂时写不出来(如果还记得的话、就补上)。(暂时题解也不能理解、、5555)

E:乌龟跑步

(dfs写这道题、很不错)http://blog.csdn.net/albertluf/article/details/79603187


import java.util.Scanner;

public class E {
    static int [][][][] dp = new int [105][55][205][2];  //  没一个纬度分别表示得失、  执行第条指令、 当前所在的位置、(从100开始)、  改变指令的次数、方向为正或者负、
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
        char [] c = (" " + input.next()).toCharArray();
        int n = input.nextInt();
        dp[0][0][101][1] = 1;  //初始位置为 100、 方向为 正、、、
        for(int i = 1; i < c.length; i++){  //所遍历的 指令的个数、、
            for(int j = 0; j <= n; j++){  // 改变指令的次数、、
                for(int k = 1; k <= 202; k++){
                    if(c[i] == 'T'){
                        if(j > 0){
                            dp[i][j][k - 1][0] |= dp[i - 1][j - 1][k][0]; // 改变指令、、
                            dp[i][j][k + 1][1] |= dp[i - 1][j - 1][k][1]; // 改变指令、   
                        }
                        dp[i][j][k][0] |= dp[i-1][j][k][1];  // 不改变指令、
                        dp[i][j][k][1] |= dp[i-1][j][k][0]; // 不改变指令、、
                    } else { //  ‘F’
                        if(j > 0){
                            dp[i][j][k][0] |= dp[i - 1][j - 1][k][1]; // 改变指令、、
                            dp[i][j][k][1] |= dp[i - 1][j - 1][k][0]; // 改变指令、、
                        }
                        dp[i][j][k - 1][0] |= dp[i - 1][j][k][0]; // 不改变指令、、
                        dp[i][j][k + 1][1] |= dp[i - 1][j][k][1]; // 不改变指令、、
                    }
                }
            }
        }
        int ans = 0;
        for(int i = 0; i < 205; i++){
            if(dp[c.length - 1][n][i][0] > 0) ans = Math.max(ans, Math.abs(101-i));
            if(dp[c.length - 1][n][i][1] > 0) ans = Math.max(ans, Math.abs(101-i));
        }
        System.out.println(ans);
    }
}

F:m皇后问题

这个就是用类把皇后的坐标表示出来、(因为10w * 10w 太大了、)、定义四个比较器、

这个是二维数组的特性,可以自己去验证一下哈、

- 按横坐标排序,纵坐标为第二关键字,这样既可得到左右的不安全的皇后数量 
- 按纵坐标排序,横坐标为第二关键字,这样既可得到上下的不安全的皇后数量 
- 按横坐标与纵坐标的差值排序,横坐标为第二关键字,这样既可得到左上和右下的不安全的皇后数量 

- 按横坐标与纵坐标的和排序,横坐标为第二关键字,这样既可得到右上和左下的不安全的皇后数量

总结:二维数组的性质,处于同一个左对角线上的点,横纵差值相等,处于同一个右对角线上的点,横纵的和相等。

(啦啦啦,get新技能的喜悦)



借用别人c++代码:

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100010;
struct node {
    int x, y, id;
}queen[maxn];
int cnt[maxn], ans[10];
int n, m;
bool cmp1(node &a, node &b)
{
    if (a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}
bool cmp2(node &a, node &b)
{
    if (a.y == b.y) return a.x < b.x;
    return a.y < b.y;
}
bool cmp3(node &a, node &b)
{
    if (a.x + a.y == b.x + b.y) return a.x < b.x;
    return a.x + a.y < b.x + b.y;
}
bool cmp4(node &a, node &b)
{
    if (a.x - a.y == b.x - b.y) return a.x < b.x;
    return a.x - a.y < b.x - b.y;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d", &queen[i].x, &queen[i].y);
        queen[i].id = i;
    }
    sort(queen, queen + m, cmp1);
    for (int i = 0; i < m - 1; i++)
    {
        if (queen[i + 1].x == queen[i].x) {
            ++cnt[queen[i].id];
            ++cnt[queen[i + 1].id];
        }
    }
    sort(queen, queen + m, cmp2);
    for (int i = 0; i < m - 1; i++)
    {
        if (queen[i + 1].y == queen[i].y) {
            ++cnt[queen[i].id];
            ++cnt[queen[i + 1].id];
        }
    }
    sort(queen, queen + m, cmp3);
    for (int i = 0; i < m - 1; i++)
    {
        if (queen[i].x + queen[i].y == queen[i + 1].x + queen[i + 1].y)
        {
            ++cnt[queen[i].id];
            ++cnt[queen[i + 1].id];
        }
    }
    sort(queen, queen + m, cmp4);
    for (int i = 0; i < m - 1; i++)
    {
        if (queen[i].x - queen[i].y == queen[i + 1].x - queen[i + 1].y)
        {
            ++cnt[queen[i].id];
            ++cnt[queen[i + 1].id];
        }
    }
    for (int i = 0; i < m; i++)
        ++ans[cnt[i]];
    printf("%d", ans[0]);
    for (int i = 1; i < 9; i++)
        printf(" %d", ans[i]);
    printf("\n");
    //system("pause");
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值