列挙(網羅的アルゴリズム)
列挙は、1つずつ答えようとする問題解決戦略の一種です。つまり、直接激しくループして答えを見つけ、質問を直接参照します
例:
完全な立方体:a ^ 3 = b ^ 3 + c ^ 3 +10 ^ 3という形式の方程式は、完全な立方体方程式と呼ばれます。与えられた正の整数N(N <= 100)のプログラムを記述し、すべての組み合わせを見つけて、方程式が成り立つようにします。 。
aの値に応じて、小から大への出力。2つの完全な3次方程式のaが等しい場合、小さいbの出力が優先され、最初に小さいcの出力が同じになります。
**解決策のアイデア:**四重ループ列挙a、b、c、d、最後にa判断条件(直接暴力の解決)
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
for(int a=2;a<=n;a++)
for(int b=2;b<a;b++)
for(int c=b;c<a;c++)
for(int d=c;d<a;d++)
if(a*a*a==b*b*b+c*c*c+d*d*d)
printf("%d %d %d %d",a,b,c,d);
return 0;
}
例:
生理的サイクル:
人間の体力、感情的知性、IQのピーク日。それぞれ23日、28日、33日ごとに表示されます。誰にとっても、3つのピークが同じ日に落ちるときを知りたいです。別の指定日dが与えられ、3つのピークが現れる(必ずしも最初のピークが現れる日とは限りません)日p、e、およびiが与えられ、タスクが日dを出力することである場合、次の3つピークが同じ日に当たる日(距離d日で示されます)
入力:
4つの整数(p、e、i、d )を入力します。p、e、iはそれぞれ、身体的、感情的、知的ピークが発生する日を表します。dは与えられた日です。p、e、i未満の場合があります。指定されたすべての日は負ではなく、365以下であり、要求された日は21252以下です。
出力:
指定された日から、同じ日の次の3つのピーク日(指定された日からの日数)。
問題解決のアイデアは、一般にループに判断を追加することです。そのため、ループをより速くしてループの数を減らすことができます。コアは次のとおりです
for(k=d+1;(k-p)%23;k++)
for(;(k-e)%28;k+=23)
for(;(k-i)%33;k+=23*28)
printf("%d",k-d);
例:
Xiaohengは最近「ボンバーマン」ゲームに夢中になりました。ゲームのボンバーマンを覚えていますか?爆弾を使って敵を破壊します。画面上のすべての敵を排除し、レベルを通過するために壁に隠された隠されたドアを見つける必要があります。
現在、次のような特別なレベルがあります。爆弾は1つだけですが、この爆弾は超強力です(殺害距離が長すぎるため、殺害範囲内のすべての敵を破壊できます)。最も多くの敵を排除するために爆弾をどこに置くことができますか?
最初にこのマップをモデル化します。壁は#で示されます。ここには2種類の壁があります。1つは爆破でき、もう1つは爆破できません。ただし、爆弾は1つしかないため、すべて#で示され、爆弾は壁を通過できません。敵はG、オープンスペースはと表示されますが、爆弾はオープンスペースにのみ配置できます。13 13と
入力します##############GG.GGG#GGG。#### 。#G#G#G#G ##…#…G##G #。###。#G #G##GG.GGG。#。GG## G#。#G#。#。### ## G…G…##G #。#G ###。#G ##…G#GGG.GG ##G#。 #G#G#。#G ##GG.GGG#G.GG ##############出力:8
#include<stdio.h>
int main()
{
char a[20][21];
int i,j,sum,map=0,p,q,x,y,n,m;
scanf("%d%d",&n,&m); //n代表行,m代表列
for(i=0;i<n;i++)
scanf("%s",a[i]);
for(i=0;i<n-1;i++)
{
for(j=0;j<m;j++)
{
if(a[i][j]=='.') //如果是空地
{
sum=0; //记录炸弹数
x=i;y=j; //x和y记录此时的i和j
while(a[x][y]!='#') //不是墙
{
if(a[x][y]=='G') //是怪物
sum++;x--; //向上走
}
x=i;y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;x++; //向下走
}
x=i;y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;y--; //向左走
}
x=i;y=j;
while(a[x][y]!='#')
{
if(a[x][y]=='G')
sum++;y++; //向右走
}
if(sum>map) //储存最大值
{
map=sum;p=i; //记录地点
q=j;
}
}
}
}
printf("将炸弹放在(%d,%d)处,最多可消灭%d个敌人。\n",p,q,map);
return 0;
}
``