实验08 结构化程序设计

1.

#include<stdio.h> 
int a[100],p=0,sum;
void dfs(int m,int n){
    if(m==0) {
        printf("%d=",sum);
        for(int i=0;i<p-1;i++){
            printf("%d+",a[i]);
        }
        printf("%d\n",a[p-1]);
        return;
    }
    for(int i=n;i;i--){
        a[p++]=i;//试探
        if(m-i>=0) dfs(m-i,i);
        p--;
    }
}
int main(void){
    scanf("%d",&sum);
    dfs(sum,sum-1);
    return 0;
}

2.

#include<stdio.h>
int check(int m);
int k=0,a[1000],n;
void Queen(int r){
    int i;
    for(i=1;i<=n;i++){
        a[n-r+1]=i;//试探
        if(check(n-r+1)){
            if(r>1)
                Queen(r-1);
            else
                k++;
        }
    }
}
int check(int r){//检查是否合法
    int i;
    for(i=1;i<r;i++){
        if(a[i]==a[r])return 0;
        if(a[i]-i==a[r]-r)return 0;
        if(a[i]+i==a[r]+r)return 0;
    }
    return 1;
}
int main(void){
    scanf("%d",&n);
    Queen(n);
    printf("%d",k);
    return 0;
}

3.

#include<stdio.h>
int w=1;
int k=0,a[100]={0},n,b[100][100]={0};//数组b用来存放满足条件的棋盘
#define n 8
void Queen(int r)
{
    int i;
    for(i=1;i<=n;i++)
    {
        a[n-r+1]=i;
        if(check(n-r+1))
        {
            if(r>1)
                Queen(r-1);
            else
            {
                if(check2()==0)
                    put();
            }
        }
    }
}
int check(int r){//检查皇后位置是否合法
    int i;
    for(i=1;i<r;i++)
    {
        if(a[i]==a[r])return 0;
        if(a[i]-i==a[r]-r)return 0;
        if(a[i]+i==a[r]+r)return 0;
    }
    return 1;
}
void leftright(){//左右对称
    int i,c[100];
    for(i=1;i<=n;i++)
        c[n-i+1]=a[i];
    for(i=1;i<=n;i++)
        a[i]=c[i];
}
void updown(){//上下对称
    int i,c[100];
    for(i=1;i<=n;i++)
        c[i]=n+1-a[i];
    for(i=1;i<=n;i++)
        a[i]=c[i];
}
void seconddiagonal(){//副对角线对称 
    int i,j,c[100];
    for(i=1;i<=n;i++)
    {
        j=a[i];
        c[j]=i;
    }
    for(i=1;i<=n;i++)
        a[i]=c[i];
}
void firstdiagonal(){//主对角线对称; 
    int i,j,c[100];
    for(i=1;i<=n;i++){
        j=a[i];
        c[n+1-j]=n+1-i;
    }
    for(i=1;i<=n;i++)
        a[i]=c[i];
}
int check2(void){//检查是否和之前的摆法有本质区别
    int i;
    leftright();
    if(check3()){
        leftright();//特别注意!由于a数组为全局变量,变换完后要变换回去。
        return 1;
    }
    else
        leftright();
    updown();
    if(check3()){
        updown();
        return 1;
    }
    else
        updown();
    seconddiagonal();
    if(check3()){
        seconddiagonal();
        return 1;
    }
    else
        seconddiagonal();
    firstdiagonal();
    if(check3()){
        firstdiagonal();
        return 1;
    }
    else
        firstdiagonal();
    firstdiagonal();//顺时针旋转 90° 
    updown();
    if(check3()){
        updown();
        firstdiagonal();
        return 1;
    }
    else{
        updown();
        firstdiagonal();
    }
    seconddiagonal();//逆时针旋转90° 
    leftright();
    if(check3()){
        leftright();
        seconddiagonal();
        return 1;
    }
    else{
        leftright();
        seconddiagonal();
    }
    updown();//顺时针旋转180° 
    leftright();
    if(check3()){
        leftright();
        updown();
        return 1;
    }
    else{
        leftright();
        updown();
    }
    seconddiagonal();
    updown();
    if(check3()){
        updown();
        seconddiagonal();
        return 1;
    }
    else{
        updown();
        seconddiagonal();
    }
    return 0;//无重复 
}
int check3(void){//一个用来检查变化后的a是否与b中元素相同的函数
    int i,j,flag=0;
    for(i=1;i<=w;i++){
        for(j=1;j<=n;j++){
            if(a[j]==b[i][j])
                flag++;

        }
        if(flag==n)
            return 1;//有重复 
        else
            flag=0;
    }
    return 0;
}
void put(void){//将满足条件的棋盘存入b中
    int i;
    for(i=1;i<=n;i++)
        b[w][i]=a[i];
        w++;
}
void PRINTF(void){//打印
    int i,j;
    for(i=1;i<w;i++){
        printf("No%d:",i);
        for(j=1;j<=n;j++){
            printf("%d ",b[i][j]);
        }
        if(i!=w-1)printf("\n");
    }
}
int main(void){
    Queen(n);
    PRINTF();
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值