论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > C语言程序设计教程
Tag:新手,函数,指针,数据类型,对象,Turbo,入门,运算符,数组,结构,二级,,tc,游戏,试题,问答,编译,视频教程

C趣味程序百例(18)

文章类别:C语言程序设计 | 发表日期:2008-9-24 14:44:47


58.拉丁方

59.填表格
60.1~9分成1:2:3的三个3位数




58.拉丁方
    构造 NXN 阶的拉丁方阵(2<=N<=9),使方阵中的每一行和每一列中数字1到N只出现一次。如N=4时:
            1  2  3  4
            2  3  4  1
            3  4  1  2
            4  1  2  3
*问题分析与算法设计
    构造拉丁方阵的方法很多,这里给出最简单的一种方法。观察给出的例子,可以发现:若将每 一行中第一列的数字和最后一列的数字连起来构成一个环,则该环正好是由1到N顺序构成;对于第i行,这个环的开始数字为i。按照 此规律可以很轻易的写出程序。下面给出构造6阶拉丁方阵的程序。
*程序与程序注释
#include<stdio.h>
#define N 6                /*确定N值*/
void main()
{
    int i,j,k,t;
    printf("The possble Latin Squares of order %d are:\n",N);
    for(j=0;j<N;j++)                /*构造N个不同的拉丁方阵*/
    {
        for(i=0;i<N;i++)
        {
            t=(i+j)%N;        /*确定该拉丁方阵第i 行的第一个元素的值*/
            for(k=0;k<N;k++)  /*按照环的形式输出该行中的各个元素*/
                printf("%d",(k+t)%N+1);
            printf("\n");
        }
        printf("\n");
    }
}
*运行结果
    The possble Latin Squares of order 6 are:
    1 2 3 4 5 6            2 3 4 5 6 1            3 4 5 6 1 2
    2 3 4 5 6 1            3 4 5 6 1 2            4 5 6 1 2 3
    3 4 5 6 1 2            4 5 6 1 2 3            5 6 1 2 3 4
    4 5 6 1 2 3            5 6 1 2 3 4            6 1 2 3 4 5
    5 6 1 2 3 4            6 1 2 3 4 5            1 2 3 4 5 6
    6 1 2 3 4 5            1 2 3 4 5 6            2 3 4 5 6 1

    4 5 6 1 2 3            5 6 1 2 3 4            6 1 2 3 4 5
    5 6 1 2 3 4            6 1 2 3 4 5            1 2 3 4 5 6
    6 1 2 3 4 5            1 2 3 4 5 6            2 3 4 5 6 1
    1 2 3 4 5 6            2 3 4 5 6 1            3 4 5 6 1 2
    2 3 4 5 6 1            3 4 5 6 1 2            4 5 6 1 2 3
    3 4 5 6 1 2            4 5 6 1 2 3            5 6 1 2 3 4

----------------------------------------------------------------

59.填表格
    将1、2、3、4、5和6 填入下表中,要使得每一列右边的数字比左边的数字大,每一行下面的数字比上面的数字大。按此要求,可有几种填写方法?
. . .
. . .


*问题分析与算法设计
    按题目的要求进行分析,数字1一定是放在第一行第一列的格中,数字6一定是放在第二行第三列的格中。在实现时可用一个一维数组表示,前三个元素表示第一行,后三个元素表示第二行。先根据原题初始化数组,再根据题目中填 写数字的要求进行试探。
*程序与程序注释
#include<stdio.h>
int jud1(int s[]);
void print(int u[]);
int count;                /*计数器*/
void main()
{
    static int a[]={1,2,3,4,5,6};    /*初始化数组*/
    printf("The possble table satisfied above conditions are:\n");
    for(a[1]=a[0]+1;a[1]<=5;++a[1])          /*a[1]必须大于a[0]*/
        for(a[2]=a[1]+1;a[2]<=5;++a[2])      /*a[2]必须大于a[1]*/
            for(a[3]=a[0]+1;a[3]<=5;++a[3])   /*第二行的a[3]必须大于a[0]*/
                for(a[4]=a[1]>a[3]?a[1]+1:a[3]+1;a[4]<=5;++a[4])
                                              /*第二行的a[4]必须大于左侧a[3]和上边a[1]*/
                    if(jud1(a)) print(a);       /*假如满足题意,打印结果*/
}

int jud1(int s[])
{
    int i,l;
    for(l=1;l<4;l++)
        for(i=l+1;i<5;++i)
            if(s[l]==s[i])  return 0;    /*若数组中的数字有重复的,返回0*/
    return 1;                            /*若数组中的数字没有重复的,返回1*/
}

void print(int u[])
{
    int k;
    printf("\nNo.:%d",++count);
    for(k=0;k<6;k++)
        if(k%3==0)           /*输出数组的前三个元素作为第一行*/
            printf("\n%d",u[k]);
        else                 /*输出数组的后三个元素作为第二行*/
            printf("%d",u[k]);
}
*运行结果
    The possble table satisfied above conditions are:
    No.1:        No.2:        No.3:        No.4:        No.5:
    1 2 3        1 2 4        1 2 5        1 3 4        1 3 5
    4 5 6        3 5 6        3 4 6        2 5 6        2 4 6

--------------------------------------------------------

60.1~9分成1:2:3的三个3位数
    将1到9 这九个数字分成三个3位数,分求第一个3位数,正好是第二个3位数的二倍,是第三个3位数的三倍。问应当怎样分法。
*问题分析与算法设计
    问题中的三个数之间是有数学关系的,实际上只要确定第一个三位数就可以解决问题。
    试探第一个三位数之后,计算出另外两个数,将其分别分解成三位数字,进行判定后确定所试探的数是否就是答案。
    需要提醒的是:试探的初值可以是123,最大值是333。因为不可能超出该范围。
*程序与程序设计
#include<stdio.h>
int ok(int t,int *z);
int a[9];
void main()
{
    int m,count=0;
    for(m=123;m<=333;m++)           /*试探可能的三位数*/
        if(ok(m,a)&&ok(2*m,a+3)&&ok(3*m,a+6))      /*若满足题意*/
            printf("No.%d:  %d %d %d\n",++count,m,2*m,3*m);    /*输出结果*/
}

int ok(int t,int *z)     /*分解t的值,将其存入z指向的三个数组元素,若满足要求返回1*/
{
    int *p1,*p2;
    for(p1=z;p1<z+3;p1++)
    {
        *p1=t%10;               /*分解整数*/
        t/=10;
        for(p2=a;p2<p1;p2++)     /*查询分解出的数字是否已经出现过*/
            if(*p1==0||*p2==*p1)return 0;    /*若重复则返回*/
    }
    return 1;                /*否则返回1*/
}
*运行结果
        No.1:192   384   576
        No.2:219   438   657
        No.3:273   546   819
        No.4:327   654   981

*思考题
    求出所有可能的以下形式的算式,每个算式中有九个数位,正好用尽1到9这九个数字。
    1)○○○+○○○=○○○                (共有168种可能的组合)
    2)○×○○○○=○○○○               (共有2种可能的组合)
    3)○○×○○○=○○○○               (共有7种可能的组合)
    4)○×○○○=○○×○○○             (共有13种可能的组合)
    5)○×○○○=○×○○○○             (共有28种可能的组合)
    6)○○×○○=○×○○○○             (共有7种可能的组合)
    7)○○×○○=○○×○○○             (共有11种可能的组合)

上一篇:{实例}C趣味程序百例(17) 人气:5327
下一篇:{实例}C趣味程序百例(19) 人气:5125
视频教程列表
文章教程搜索
 
C语言程序设计推荐教程
C语言程序设计热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058