[2021年春の募集]アリ筆記試験本当の質問

若いアイドラー、古い物乞い!

だが

2021.3.6

1411. N x3グリッドマップを色付けするためのスキームの数815.
バスルート

1

nx 3グリッドがあります。各グリッドを赤、黄、緑の3色のいずれかで色付けし、隣接するグリッドの色が異なることを確認する必要があります(つまり、水平または垂直の側面が同じグリッド)。異なっています)。グリッドグラフnの行数を指定します。
グリッドの配色数を返送してください。答えは非常に大きい可能性があるため、残りの答えの結果を10 ^ 9 +7に返してください。
ここに画像の説明を挿入します

法則を見つけ、動的な計画

class Solution {
    
    
    static final int MOD = 1000000007;

    public int numOfWays(int n) {
    
    
        long fi0 = 6, fi1 = 6;
        for (int i = 2; i <= n; ++i) {
    
    
            long newFi0 = (2 * fi0 + 2 * fi1) % MOD;
            long newFi1 = (2 * fi0 + 3 * fi1) % MOD;
            fi0 = newFi0;
            fi1 = newFi1;
        }
        return (int) ((fi0 + fi1) % MOD);
    }
}

2

一連のバスルートを表す一連のルートを指定します。各ルート[i]はバスルートを表し、i番目のバスがその上を循環します。

たとえば、ルートroutes [0] = [1、5、7]は、0番目のバスが常に1-> 5-> 7-> 1-> 5-> 7-> 1->…などのシーケンスに従うことを意味します。駅ルート運転。
ここで、ソースステーション(最初はバス上ではありません)から開始して、ターゲットステーションに向かいます。この期間中はバスのみご利用いただけます。

乗るバスの最小数を見つけます。ターミナル駅に行けない場合は、-1を返します。

BFS:幅優先探索、

import java.util.Arrays;

class Solution {
    
    
    public int numBusesToDestination(int[][] routes, int source, int target) {
    
    
		int maxStationNum = 0;//最大车站编号
        //统计最大车站编号
		for(int[] route:routes){
    
    
			for(int num: route){
    
    
				maxStationNum = Math.max(maxStationNum, num);
			}
		}
        //终点车站比最大的大,即不存在,直接返回
        if(target > maxStationNum){
    
    
            return -1;
        }
        //用来存储每个车站距离source站换车次数
		int[] dp = new int[maxStationNum+1];
		Arrays.fill(dp, maxStationNum+1);//初始设置为不可达,maxStationNum+1表示不可达
        //设置起点可达需要0次
		dp[source] = 0;

        //用来标记车数组中是否发生修改
		boolean updateFlag = true;
        //广度优先遍历
		while(updateFlag){
    
    
            //每一轮遍历车数组
			for(int[] route:routes){
    
    
                //统计当前车次中可达终点的最小次数
				int min = maxStationNum+1;
				for(int num: route){
    
    
					if(dp[num] < min){
    
    
						min = dp[num];
					}
				}
                //根据最小次数,更新同一个车次中,其他站的最小次数
				for(int num: route){
    
    
					if(dp[num] > min+1){
    
    
						dp[num] = min+1;
						updateFlag = false;//标志数组发生修改
					}
				}
			}
            //如果发生修改,即所有数组中站点修改完成,为false
            //如果没有发生修改,即所有数组中站点修改完成,为true
			updateFlag = !updateFlag;//如果全部修改完成,终止while循环
		}
        //返回到达target的最小次数
		if(dp[target] < maxStationNum+1){
    
    
			return dp[target];
		}
		return -1;
	}	
}

2021.3.8

1539.kが正の整数を欠いている
879.利益計画

1

正の整数arrと整数kの配列を厳密な昇順で与えます。

この配列でk番目に欠落している正の整数を見つけてください。

アナログカウントプロセス

class Solution {
    
    
    public int findKthPositive(int[] arr, int k) {
    
    
        int count = 0;
        int miss = 0;
        for(int i = 0; i < arr.length; i++){
    
    
            count++;
            while(count < arr[i]){
    
    
                miss++;
                if(miss == k){
    
    
                    return count;
                }
                count++;
            }
        }
        return arr[arr.length-1]+k-miss;
    }
}

2

グループにはn人の従業員がいて、さまざまな仕事をして利益を上げることができます。

i番目のジョブはprofit [i]を生成します。これには、group [i]メンバーの参加が必要です。メンバーがこれらのタスクの1つに関与している場合、他のタスクに参加することはできません。

少なくともminProfitの利益を生み出す作業のサブセットは、利益計画と呼ばれます。そして、働くメンバーの総数はせいぜいnです。

いくつのプランから選択できますか?答えが非常に大きいため、10 ^ 9 +7を法とする結果が返されます。

dp、ナップサック問題は似ています

class Solution {
    
    
    public int profitableSchemes(int G, int P, int[] group, int[] profit) {
    
    
        int mod = 1000_000_007;
        int[][] dp = new int[G + 1][P + 1];
        //dp[i][j]表示,分配j个工人收益i的收益计划数量
        //dp数组从最后一行向前,
        
        dp[0][0] = 1;
        int taskNum = group.length;
        //动态规划
        for (int i = 0; i < taskNum; i++) {
    
    //首先是遍历每一个任务
            int workerNum = group[i];//当前任务的工人数量
            int workProfit = profit[i];//当前任务带来的收益
            for (int j = G; j >= workerNum; j--) {
    
    
                for (int k = P; k >= 0; k--) {
    
    
                    int indexK = 0;
                    if(workProfit < k){
    
    
                        indexK = k - workProfit;
                    }
                    dp[j][k] = (dp[j][k] + dp[j-workerNum][indexK])%mod;
                }
            }
        }
		
        int sum = 0;
        for (int i = 0; i < G+1; i++){
    
    
            sum = (sum + dp[i][P])%mod;
        }
        return sum;
    }
}

2021.3.10

最初の質問:Leetcode1388.3n個のピザが見つかりませんでした

1

タイトル説明:

シミュレーションの質問、一方向にしか行けない、壁にぶつかって停止する、4つの方向
は入力の読み取りに使用されない、nextIntはnextLineで読み取る必要がある\ n、-_-
@は開始点を示し、#は壁を示す、南東、北西方向の
入力を入力してください:
3 4 4
@…
。#
……
EAST
SOUTH
WEST
NORTH
出力:
1 3

2

これがピザです。サイズの異なる3n個のピース​​で構成されています。次に、あなたとあなたの友達は、次のルールに従ってピザを分割する必要があります。

あなたはピザの任意の部分を選びます。
アリスはあなたが選んだ次のピザを反時計回りに選びます。
ボブは時計回りに次のピザを選びます。
ピザがなくなるまで、上記のプロセスを繰り返します。
ピザの各スライスのサイズは、時計回りの円形配列スライスで表されます。

入手できるピザの最大サイズを返送してください。
ここに画像の説明を挿入します

値の合計を最大化するために、循環3nシーケンスでn個の隣接しない数値を選択します

class Solution {
    
    
    public int maxSizeSlices(int[] slices) {
    
    
        int[] slices1 = new int[slices.length - 1];
        System.arraycopy(slices, 1, slices1, 0, slices.length - 1);
        int[] slices2 = new int[slices.length - 1];
        System.arraycopy(slices, 0, slices2, 0, slices.length - 1);
        int ans1 = calculate(slices1);
        int ans2 = calculate(slices2);
        return Math.max(ans1, ans2);
    }

    public int calculate(int[] slices) {
    
    
        int n = slices.length;//序列长度是原本序列长度-1,可选择披萨数量少1
        int choose = (n + 1) / 3;//因为是去掉了头尾计算的,所以可选择披萨要加1
        int[][] dp = new int[n + 1][choose + 1];
        for (int i = 1; i <= n; ++i) {
    
    
            for (int j = 1; j <= choose; ++j) {
    
    
                dp[i][j] = Math.max(dp[i - 1][j], (i - 2 >= 0 ? dp[i - 2][j - 1] : 0) + slices[i - 1]);
            }
        }
        return dp[n][choose];
    }
}

ノート

  1. リングについて:[0、last-1]と[1、last]の値をそれぞれ計算し、最大値を見つけます
  2. Dajiajieshe 2との違いについて:合計nのシーケンスで、Dajia2はn / 2の部屋を盗むことができ、ピザはn / 3のスライスを取ることができます。

2021.3.12

1


有向グラフのBFSは、有向グラフを示し、aからbまでの最短距離を尋ねます。

解決策:有向グラフダイクストラ

2

n * nチェス盤には「車」があり、「車」を斜めの位置に動かし、移動中に他の「車」に食べられないようにします。最小移動回数を求めます
。C。ピースフルルーク

おすすめ

転載: blog.csdn.net/qq_39457586/article/details/114489390