C++で解く!N回のカットで得られる最大ピース数の求め方
問題概要
1枚の正方形のピースに対して、合計N回の水平方向または垂直方向のカットを加えるとき、同じ大きさの正方形・長方形のピースを最大でいくつ作れるかを求めるのがこの問題です。
まず、具体例を使って問題の内容を確認していきましょう。
例1
入力 − N = 8
出力 − 25
説明 − N = 8 の場合、垂直方向のカット数は4回、水平方向のカット数は4回となります。
合計ピース数 = 25
| 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 |
例2
入力 − 7
出力 − 20
| 1 | 2 | 3 | 4 | 5 |
| 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 |
アルゴリズムの考え方
カットの総数Nが与えられたとき、ピース数を最大化するには、水平方向と垂直方向のカット数をできるだけ均等に分配する必要があります。
Nが偶数であれば水平・垂直ともに同数のカットとなり、Nが奇数であればどちらか一方が他方より1回多くなります。
したがって、水平方向のカット数 = N/2、垂直方向のカット数 = N−H と表せます。
関数MaxPieces()の中で、水平方向のカット数を格納するint型変数Hを N/2 で初期化します。
続いて、垂直方向のカット数を格納するint型変数Vを N−H で初期化します。
H回のカットで区切られる行は H+1 本、V回のカットで区切られる列は V+1 本になるため、最終的なピース数は次の式で求められます。
ピース数 = (水平方向の区画数) × (垂直方向の区画数) = (H+1) × (V+1)
C++での実装例
#include <bits/stdc++.h>
using namespace std;
int MaxPieces(int N){
//Hは水平方向のカット数
int H = N / 2;
//Vは垂直方向のカット数
int V = N-H;
//最大ピース数 = (H+1)*(V+1)
return ((H + 1) * (V + 1));
}
//メイン関数
int main(){
//カットの総数
int N = 7;
cout << "Max pieces = "<<MaxPieces(N);
return 0;
}
実行結果
上記のコードを実行すると、次の出力が得られます。
Max pieces = 20
-
二分木で屈曲数が最大となるパスの長さを求めるC++プログラム
本記事では、二分木が与えられたときに、屈曲数が最大となるパスを求める問題を解いていきます。ここで「屈曲(ベンド)」とは、パスの進行方向が左から右へ、または右から左へと切り替わる箇所のことです。具体例を見てみましょう。入力 −出力 −6この方法では、木を走査しながら直前の移動方向を記録していきます。方向が変化した時点で屈曲数を加算し、最終的にその最大値を求めます。解法のアプローチこのアプローチでは、すべてのパスを辿り、各パスにおける屈曲の総数を計算します。葉ノードに到達した時点で、これまでの屈曲数が現在の最大値を上回っていれば、答えとパスの長さを新しい値に更新します。C++による実装例#incl
-
C++で円をN回カットしたときのピース数を計算する方法
問題の概要整数Nが与えられます。このNは、2次元平面上の円に対して加える「カット(切り込み)」の回数を表します。1回のカットによって円は2つに分けられるため、N回のカットを行った後に円がいくつのピースに分割されるかを求めるのが、この問題の目的です。計算式この問題はとてもシンプルで、次の式で答えを求めることができます。ピースの数 = 2 × カットの回数(N)各カットが円の中心を通って切断されると考えると、カット1回ごとにピースが2つずつ増えていくため、この式が成り立ちます。具体例入力: N = 1出力: 円のピース数: 2説明: 1回のカットで、円はちょうど2つの半分に分けられます。入力: N