数据结构与算法之循环算法
循环算法基本概念
我们借助计算机快速处理数据的功能,让计算机重复的加工计算,这就构成了循环算法,其关键在于构建循环条件和循环体。
循环条件:每个循环有其循环的开始和结束的条件,否则死循环。
循环体:每次循环执行的步骤、变量、代码形式一致,而变量内存的数据发生改变。
基本的设计方法如下两种:
“自顶向下”的循环算法设计方法
自顶向下的设计方法是从全局走向局部、从策略走向详尽的设计方法。自顶向下是系统分解和细化的过程。
首先,根据题意,总体规划设计算法的主要组成或步骤。
其次,分别对各个步骤进行分解,理清各个子步骤的算法框架。
最后,继续为各个子步骤算法进行细化,直至算法实现。
由具体到抽象设计循环结构
从给定的问题的具体特点为依据进行算法设计。由具体实例进行归纳,可以比较容易地得到抽象的表达式。
首先:仔细了解问题的含义,从具体的问题中,归纳或抽象出具有普遍意义的共同特征。
其次:根据归纳得到的共同特征,设计算法,构造出“不变式”的“循环条件”和“循环体”。
最后:将问题进一步进行逐步细化, 最终得到解决问题的算法。
循环算法代码粗讲
自顶向下
问题: 由1、2、3、4、5、6个数字组成不同数字的6位数,前1位能被1整除,前2位能被2整除,…,前6位能被6整除,求这样的6位数供有多少个?
分析:总体分析得奇数位(第1、3、5位)为奇数(且5在第五位),偶数位为偶数。
对偶数的判断:
4只能在第六位:
不能在第四位:第三位数只能为1或3, 14、34都不能被4整除,即前四位不能被4整除。
不能在第二位:1+3+4=8不能被3整除,即前三位不能被3整除。
6只能在第四位:若在第二位则1+3+6=10,不能满足前三位被3整除。
2只能在第二位。
对奇数位的判断:
5只能在第五位,才能满足前五位能被5整除。
1、3无法判断。
上述通过数论方法进行的分析可以得到两个解。
#include <cstdio.h>
using namespace std;
int main()
{
int a,b,c,d,e=5,f,count=0;
for(a=1;a<5;a=a+2){
for(b=2;b<=6;b=b+2){
for(c=1;c<5;c=c+2){
if(a==c|| (a+b+c)%3!=0) continue;
for(d=2;d<=6;d=d+2){
if(b==d||(10*c+d)%4!=0)
continue;
for(f=2;f<=6;f=f+2){
if(b=f||d==f) continue;
count++;
}
}
}
}
}
return 0;
}
具体到抽象
问题: 33…3(2006个3)减去77*…*7(100个7),得到的个位数和十位数字是多少?
分析:
可看成am–bn的最后两位数。
分别求取am、bn 的 末尾两个数
将结果相减在加上100用100取余即可得到问题的解
#include<cstdio.h>
using namespace std;
int main(){
int i,j,a=1,b=1;
for(i=1;i<=2006;i++)
a=a*3%100;
for(i=1;j<=100;j++)
b=b*7%100;
printf(“%d\n”,(a-b+100)%100);
return 0;
}
比赛安排
问题:
设有2 n(n<=6)个球队进行单循环比赛,计划在2 n – 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2 n – 1天内每个队都与不同的对手比赛。
例如n=2时的比赛安排:
队 1 2 3 4
比赛 12 34 一天
13 24 二天
14 23 三天
分析:
用二维数组is来判断两个队之间是否进行过比赛0 没有 1 有
用一维数组vis进行该轮各队是否已经安排,0未安排1安排
#include<bits/stdc++.h>
using namespace std;
bool is[505][505],vis[505];
int main(){
int n;scanf("%d",&n);
memset(is,0,sizeof(is)); //数组初始化为 0
int T=(1<<n)-1;//2的n次方-1
int ans=0; //第几轮
while(T--) {
memset(vis,0,sizeof(vis)); //初始化数组0
printf("<%d>",++ans);
bool bb=0; //第一次打印标志
for(int i=1;i<=(1<<n);i++)
{
if(!vis[i]) //若该队未安排
{
vis[i]=1;
for(int j=i+1;j<=(1<<n);j++) //寻找比赛对手
{
if(!vis[j]&&!is[i][j]) //对应的队未安排,且没有进行过比赛
{
vis[j]=1;is[i][j]=1;//安排比赛
if(bb)printf(",");
printf("%d-%d",i,j);
bb=1;break;
}
}
}
}
printf("\n");
}
return 0;
}
本文探讨了循环算法的基本概念,包括循环条件和循环体,介绍了自顶向下和具体到抽象的设计方法,并通过三个实际问题的代码示例展示了如何在不同场景下运用循环算法。涉及了数论问题、数字运算和比赛安排等场景的解决方案。

2419

被折叠的 条评论
为什么被折叠?



