0
点赞
收藏
分享

微信扫一扫

如何使用Python结合Pillow、matplotlib和OpenCV实现图片读取

以前干嘛去了 2024-03-28 阅读 6

第1章 递归函数的设计技巧

数学(结构)归纳法
  1. 验证P(1)成立
  2. 证明如果P(k)成立,那么P(k+1)成立
  3. 联合Step1和Step2,证明P(1)->P(n)成立
递归函数
  1. 给递归函数一个明确的语义
  2. 实现边界条件时的程序逻辑(p(1))
  3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑 ( p(k) )
//递归 n的阶乘
//1.acm_1_1_diGui_test6代表n的阶乘的结果
int acm_1_1_diGui_test(int n){
if(n==1)return 1; //边界条件 n==1
return acm_1_1_diGui_test(n-1)*n; //利用f(n-1)结果计算f(n)的值
}

//猴子吃桃
//猴子吃n天桃子的数量
int acm_1_1_diGui_test2(int n){
if(n==1)return 1;
return (acm_1_1_diGui_test2(n-1)+1)*2;
}

例题

一个小球,掉落到一连串弹簧板上,每个弹簧板回弹a[i]个距离,问小球弹 几次会弹出弹簧板串

i=0
res=0
n=int(input())
ns=list(map(int,input().split(" ")))
while(i<n):
    i+=ns[i]
    res+=1
print(res)

例题:

输出n的指数型枚举

int arr[10]; 
def fn(int i,int j,int n){
if (j>n) return;
for(int k=j;k<=n;k++){ //j代表最小值,只能输出从j到n
arr[i]=k;//i代表第几个位置, 其中arr[j]一定比arr[i]前面的都大
print_one_result(i); //输出前i个,i表示到了第几个位置
fn(i+1,j+1,n);
}
}

//输出从arr数组从0到n的元素
void print_one_result(int n){
cout << "n" << n << endl;
for(int i=0;i<=n;i++){
if(i){
cout << " ";
}
cout << arr[i];
}
cout << endl;
}
int n;
cin >> n; //对n进行指数枚举
acm_1_1_diGui_fn3(0,1,n);
f(n)的n==ikarrji
01110
121 221
231 2 332
131 321
02210
132 331
03310

结论:

arr=[0]*10
def print_one_result(n):
    for i in range(0,n+1):
        if i:
            print(" ",end="")
        print(arr[i],end="")
    print()


def fn3(i,j,n):
    if(j>n): return;
    for k in range(j,n+1):
        arr[i]=k
        print_one_result(i)
        fn3(i+1,k+1,n);

def fn3_Test():
    n=int(input())
    fn3(0,1,n)
fn3_Test()

例题:

递归实现组合型枚举

void acm_1_1_print_one_result5(int n){
for(int i=0;i<n;i++){
if (i) cout << " ";
cout << arr[i];
}
cout << endl;
}
void acm_1_1_diGui_fn5(int i,int j,int n,int m){
if(i==m){
acm_1_1_print_one_result5(m);
return;
}
for(int k=j;k<=n && m-i-1<=n-k;k++){
arr[i]=k;
acm_1_1_diGui_fn5(i+1,k+1,n,m);
}
return;
}
void acm_1_1_diGui_test5(){
int n,m; //n代表输入是几 ,m代表每次输出几个数
cin >> n >> m;
acm_1_1_diGui_fn5(0,1,n,m);
//0 代表第几个位置
//1 代表当前位置最小可以选择的值
//n 代表当前位置最大可以选择的值
//m 最多枚举多少倍
}

例题:

按照字典序列,输出所有1到n这n个整数的所有方案

//按照字典序输出所有1到n这n个整数的方案
int arr6[10],vis6[10]={0};
void acm_1_1_print_one_result6(int n){
for(int i=0;i<n;i++){
if(i) cout << " ";
cout << arr6[i];
}
cout << endl;
return;
}
void acm_1_1_diGui_fn6(int i,int n){
if(i==n){
//开始输出
acm_1_1_print_one_result6(n);
return;
}
for(int k=1;k<=n;k++){
if(vis6[k])continue; //k被使用过了
arr6[i]=k;
vis6[k]=1;
acm_1_1_diGui_fn6(i+1,n);
vis6[k]=0; //回收k
}
}
void acm_1_1_diGui_test6(){
int n; //n代表输入是几 ,m代表每次输出几个数
cin >> n;
acm_1_1_diGui_fn6(0,n);
//0 代表第几个位置
//1 代表当前位置最小可以选择的值
//n 代表当前位置最大可以选择的值
//m 最多枚举多少倍
}
acm_1_1_diGui_test6();

例题:

239不规则的街道

//分形图形
void acm_1_1_diGui_fn7(long long n,long long s,long long &x,long long &y){
//递归函数,求n级城市中,房子编号为s的房子坐标并将坐标存储在(x,y)变量中
if(n==1){//当为1级城市的时候,直接返回
if (s==1) x=0,y=0;
else if(s==2) x=0,y=1;
else if(s==3) x=1,y=1;
else x=1,y=0;
return;
}
long long L=1LL << (n-1);
long long block=L*L; //每个区域点的数量
long long xx,yy;
//当前点在第几个区域中
if (s <= block ) { //第一个区域,用坐标变换规则:(x,y)->(y,x)

acm_1_1_diGui_fn7(n-1,s,xx,yy);
x=yy,y=xx;
}else if(s <= 2*block){ //第二个区域,(x,y)->(x,y+L)
acm_1_1_diGui_fn7(n-1,s-block,xx,yy);
x=xx,y=yy+L;
}else if(s <= 3*block){ //第三个区域,(x,y)->(x+L,y+L)
acm_1_1_diGui_fn7(n-1,s-2*block,xx,yy);
x=xx+L,y=yy+L;
}else{//第四个区域,(x,y)->(2L-y-1 ,L-x-1)
acm_1_1_diGui_fn7(n-1,s-3*block,xx,yy);
x=2*L-yy-1,y=L-xx-1;
}
return;

}
void acm_1_1_diGui_test7(){
long long t,n,s,d;
scanf("%lld",
while(t--){
scanf("%lld%lld%lld",
long long sx,sy,dx,dy;
acm_1_1_diGui_fn7(n,s,sx,sy);
acm_1_1_diGui_fn7(n,d,dx,dy);
printf("%.0lf\n",10*sqrt(S(sx-dx)+S(sy-dy)));
}
}
void acm_1_1_diGui_test7(){
long long t,n,s,d;
scanf("%lld",
while(t--){
scanf("%lld%lld%lld",
long long sx,sy,dx,dy;
acm_1_1_diGui_fn7(n,s,sx,sy);
acm_1_1_diGui_fn7(n,d,dx,dy);
printf("%.0lf\n",10*sqrt(S(sx-dx)+S(sy-dy)));
}
}
  • 完成2024.3.5
by cry
举报

相关推荐

0 条评论