目次
質問部分
トピック | ブロックチェーンファイルダンプシステム |
困難 | 災害 |
質問の説明 | ブロックチェーンの基礎となるストレージは、連続する N 個のファイルで構成される連鎖ファイル システムであり、各ファイルのサイズは F1、F2...Fn の順に異なります。時間が経つにつれて、占有されるストレージはますます大きくなります。 クラウド プラットフォームでは、ブロックチェーンをファイルごとに安価な SATA ディスクにダンプすることを検討していますが、SATA ディスクにダンプできるのは連続したブロックチェーン ファイルのみであり、転送されたファイルの合計が SATA ディスクの容量を超えることはできません。 各 SATA ディスクの容量が M であると仮定し、ダンプできる最大の連続ファイルの合計を求めます。 |
説明を入力してください | 最初の行は SATA ディスクの容量 M、1000 <= M <= 1000000 です。 2 行目は、ブロックチェーン ファイル サイズのシーケンス F1、F2、F3...Fn です。ここで、1 <= n <= 100000、1 <= Fi <= 500。 |
出力の説明 | 保存できる連続ファイルの最大サイズの合計を求めます。 |
追加情報 | なし |
-------------------------------------------------- ---- | |
例 | |
例1 | |
入力 | 1000 100 300 500 400 400 150 100 |
出力 | 950 |
説明する | 最大シーケンス合計は 950 で、シーケンスは [400, 400, 150] です。 |
例 2 | |
入力 | 1000 100 500 400 150 500 100 |
出力 | 1000 |
説明する | 最大シーケンス合計は 1000 で、シーケンスは [100, 500, 400] です。 |
解釈と分析
質問の解釈:
ディスク ダンプを実行し、ファイル サイズの合計が回転ディスクのサイズを超えないように連続したファイルを検索し、ファイル サイズの最大合計を見つけます。直訳すると、連続する正の整数の集合から、連続する数値の合計が指定された数値を超えないように連続する数値を見つけます。条件を満たした場合の連続する数値の最大合計はいくらになりますか。
分析とアイデア:
この質問は、「 Huawei OD のコンピュータベースのテストアルゴリズムの質問: 生存不可能な Populus euphratica の再植」に似ています。どちらも、左側の境界として 0 を使用し、右側の境界を見つけて、左側の境界と右側の境界の間のすべての数値が条件を満たすようにします。次に、左右の境界を右に移動し、次に条件を満たす連続ブロックを探し、各連続ブロックの条件を1つずつ比較し、最終的に条件を満たす連続ブロックの中から最適なものを出力します(最適な条件は質問の要件によって異なります)。
この問題の時間計算量は O(n)、空間計算量は O(1) です。
コード
Javaコード
import java.util.Scanner;
/**
* 区块链文件转储系统
*
* @since 2023.09.22
* @version 0.1
* @author Frank
*
*/
public class StorageTransfer {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String input = sc.nextLine();
int limit = Integer.parseInt(input);
input = sc.nextLine();
String[] strNumbers = input.split(" ");
processStorageTransfer(limit, strNumbers);
}
}
private static void processStorageTransfer(int limit, String strNumbers[]) {
int[] numbers = new int[ strNumbers.length ];
for( int i = 0; i < strNumbers.length; i ++ )
{
numbers[i] = Integer.parseInt( strNumbers[i] );
}
int left = 0;
int right = 1;
int tmpMax = numbers[0];
int maxSize = 0;
while( right <= numbers.length )
{
while( ( right < numbers.length ) && ( tmpMax + numbers[right] <= limit ) )
{
tmpMax += numbers[right];
right ++;
}
if( tmpMax > maxSize )
{
maxSize = tmpMax;
}
if( maxSize == limit )
{
System.out.println( maxSize );
return;
}
if( right >= numbers.length )
{
break;
}
do {
tmpMax -= numbers[left];
left ++;
}while( left < numbers.length && tmpMax > limit);
}
System.out.println( maxSize );
}
}
JavaScriptコード
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
while (line = await readline()) {
var limit = parseInt(line);
line = await readline();
var strNumbers = line.split(" ");
processStorageTransfer(limit, strNumbers);
}
}();
function processStorageTransfer(limit, strNumbers) {
var numbers = new Array();
for (var i = 0; i < strNumbers.length; i++) {
numbers[i] = parseInt(strNumbers[i]);
}
var left = 0;
var right = 1;
var tmpMax = numbers[0];
var maxSize = 0;
while (right <= numbers.length) {
while ((right < numbers.length) && (tmpMax + numbers[right] <= limit)) {
tmpMax += numbers[right];
right++;
}
if (tmpMax > maxSize) {
maxSize = tmpMax;
}
if (maxSize == limit) {
console.log(maxSize);
return;
}
if (right >= numbers.length) {
break;
}
do {
tmpMax -= numbers[left];
left++;
} while (left < numbers.length && tmpMax > limit);
}
console.log(maxSize);
}
(以上)