列挙アルゴリズムとは何ですか?
列挙は、名前が示すように、最も不器用な方法(暴力的な列挙)で問題を解決するためのものです。セット列挙は、有限のシーケンスセットのすべてのメンバーをリストするプログラム、または特定のタイプのオブジェクトの数です。これら2つのタイプは、多くの場合(常にではありません)重複します。
列挙アルゴリズムは、私たちが日常生活で最もよく使用するものです。その中心的な考え方は次のとおりです。
すべての可能な
列挙方法を列挙することの本質は、すべての候補解から正しい解を検索することです。このアルゴリズムの使用は、2つの条件を満たす必要があります:(1)候補解の数は事前に決定できる、(2)候補解の範囲は解く前に特定のセットが必要です。
次のいくつかの質問は、列挙についてよりよく理解するのに役立ちます
1.フロア番号
トピックの説明:
小林はNOIPの競争の間、「ニューワールド」ホテルに滞在しました。他のホテルとは異なり、このホテルは毎日エネルギー数tが高く、床には表示されません。t= 3を例にとると、3、13、31、33などの床は存在しません。
はい、フロア番号は1、2、4、5、...です。実際の4階は3階です。小林はm階の部屋を予約していたことが知られており、当日の高エネルギー番号はtです。今、彼は部屋がどこにあるのか知りたがっています実際の階とは
1
2
3
4
説明を入力
2つの整数mとtの1行、1 <= m <= 100000、0 <= t <= 9、mがtに対して正当な
1
出力記述を持つことを保証する
実際の床表す整数ライン
1
サンプル入力を
14 3
出力例
12
アイデア:
1.この高エネルギー数を含むフロアが表示されないようにする必要があります。アルゴリズムは次のとおりです。
bool s(int a、int b){ while(a!= 0 ){ if(a%10 == b){ return false ; } a / = 10 ; } trueを返し ます。 }
2. forループを使用して合計を累積します。高エネルギー数が含まれていない場合(つまり、s(i、高エネルギー数)= true)、合計++
for(int i = 1 ; i <= m; i ++ ){ if (s(i、t)){ sum ++ ; } } cout << sum
コード:
#include <iostream> using namespace std; bool s(int a、int b){ while(a!= 0 ){ if(a%10 == b){ return false ; } a / = 10 ; } trueを返し ます。 } int main(){ int m、t、sum = 0 ; cin >> m >> t; for(int i = 1 ; i <= m; i ++ ){ 合計 ++の場合(s(i、t)){ ; } } cout << sum; 0を返し ます。 }
2.カーリング
タイトルの説明:
カーリングゲームでは、目標点Pと所定の正の整数rが与えられる。各ゲームの後に、チームAとBが交互に8回カーリングし、ゲームは終了しました。このとき、どちらの側のカールが最終的に目標点Pに近づき、その側が得点し、反対側は得点しません。各得点者は、ターゲットポイントPからの距離がr以下で、カーリング位置が他のチームのすべてのカーリングよりもターゲットポイントPに近い場合、1ポイントを獲得できます。
ゲームは10イニングまでプレイできます。2つのサイド間の試合が終了すると、遅れているサイドは棄権できます。この時点で、ゲームはもう進行していません
各ラウンドの終了時、ターゲットポイントPからの2つの側面の各カールサイドと正の整数rの間の距離は、2つのチーム間の各ラウンドのスコアと合計スコアを判断するプログラムを記述してください
入力してください:
1行目の正の整数r
その下には数行あり(20行以下)、各行は8つの正の整数(間にスペースあり)です。
2行目のj番目の数字は、パーティーAのj番目のカーリングから最初のゲームの終了時のターゲットポイントPまでの距離を示します
3行目のj番目の数字は、パーティーBのj番目のカーリングから最初のゲームの終了時のターゲットポイントPまでの距離を示してい
ます...
2k行目のj番目の数値は、パーティーAのj番目のカーリングからk番目のゲームの終了時のターゲットポイントPまでの距離を示します
2k + 1行目のj番目の数字は、パーティーBのj番目のカーリングからk番目のゲームの終了時のターゲットポイントPまでの距離を示します。
一方の当事者が途中で棄権した場合、最後の行(偶数行)には整数-1のみが含まれ、この時点で権利放棄が発生したことを示します
。
複数の行が出力され、各行に2つの整数が中央にコロンで区切られて出力され、各ゲームでの両当事者のスコアを示します(最初にスコア)。最後の行には2つの整数があり、中央がコロンで区切られており、両当事者の最終スコアを示します(最初にスコアが得られます)。
つまり、最初に「標準」rを入力します。10ゲームあり、各ゲームは8回プレイされ、最高のスコア(最新が最小)を取り、次に対戦相手の最高スコアと比較します。スコアが対戦相手よりも高い場合、スコアは標準以下になります。つまり、各ゲームでは、スコアの1つがスコアリングされていない必要があり、スコアがない場合があります。棄権した場合、直接出力して返すことができます0; 最後に、合計スコアが出力されます(カウントのみ)
1
2
3
主に列挙
入力例
12
5 60 25 74 71 100 3 93
66 75 70 66 52 73 67 14
93 84 74 99 79 64 89 22
65 5 95 59 80 8 35 61
65 61 49 60 58 50 32 85
68 38 96 38 82 64 26 93
74 92 47 21 97 30 45 78
44 99 90 27 3 46 55 34
49 45 83 3 18 1 67 23
60 47 95 81 17 1 87 85
18 74 74 84 29 20 27 71
37 60 26 56 23 65 67 49
57 7 62 92 52 5 10 69
46 97 88 28 76 27 66 7
89 89 94 31 11 11 1 0 17
19 48 35 6 77 61 45 21
52 11 76 70 73 99 85 55
90 25 20 7 64 24 94 4
3 43 32 74 10 93 35 77
77100 63 91 10 73 22 57
出力例
2:0
0:2
0:0
0:1
0:0
0:0
1:0
1:0
0:2
1:0
5:5
サンプルの説明:
標準は12であることがわかります
最初のゲームでは、Aが最低3、Bが最低14、3 <14 && 3 <= 12、Aスコア、Bはスコアなし
2番目のゲームでは、Aが最低22、Bが最低5、5 <22 && 5 <= 12、Bスコア、Aはスコアなし
3番目のゲームでは、Aの最小値は32で、Bの最小値は26です。
。。。。。。
コード
#include <iostream> #include < string > using namespace std; int main() { int r、i、j; cin >> r; int a [ 9 ]、b [ 9 ]、f = 0、f1 = 0、zf = 0、zf1 = 0、min = 10000、min1 = 100000 ; for(i = 1 ; i <= 10 ; i ++ ) { for(j = 1 ; j <= 8 ; j ++ ) { cin>> a [j]; if(a [ 1 ] ==- 1 ) { cout << zf << ' :' << zf1; 0を返し ます。 } } ため(J = 1 ; J <= 8 ; J ++ ) { CIN >> B [J]。 } for(j = 1 ; j <= 8 ; j ++ ) { if(a [j] < min) { min = a [j]; } } ため(J = 1 ; J <=8 ; j ++ ) { if(b [j] < min1) { min1 = b [j]; } } if(min < min1) { for(j = 1 ; j <= 8 ; j ++ ) { if(a [j] <= r && a [j] < min1) { f ++ ; } } cout << f << ' :' << f1 << endl; zf = zf + f; f = 0 ; } else if(min1 < min) { for(j = 1 ; j <= 8 ; j ++ ) { if(b [j] <= r && b [j] < min) { f1 ++ ; } } cout << f << ' :' << f1 << endl; zf1 = zf1 + f1; f1 = 0 ; } else { cout << 0 << ' :' << 0 << endl; } 分 = 10000 ; } cout << zf << ' :' << zf1; 0を返し ます。 }
ここでは最小値を求める方法を使用していますが、ソート後に[0]に変更することもできます。