谁来解决

djjlove_2008 2011-07-15 10:08:36
-4 - -

- - -

-8 5 -

横竖斜相加相等即可,随便怎么弄,注意前面是-4,-8,只要是整数,包括0.


要求写一段程序,找出多个答案。
...全文
292 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
玩笑 2011-08-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 djjlove_2008 的回复:]

可以改成DEV-C++运行的吧
[/Quote]
把代码改成不用变长数组的实现,并不困难,把代码全合并到主函数中,变长数组也就用不上了,,这样写只是个人的习惯,用变长数组,只是因为写起来方便
ponyzi 2011-08-06
  • 打赏
  • 举报
回复
为什么有一个1000范围的判断呢
djjlove_2008 2011-08-05
  • 打赏
  • 举报
回复
可以改成DEV-C++运行的吧
玩笑 2011-07-31
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zouyuncheng 的回复:]

引用 11 楼 djjlove_2008 的回复:

运行不了呀,你用的什么编译器?

GCC,加参数--std=c99
因为这里我用了"变长数组"这东西,为也方便传递数组参数,不用也可以,只是写起来会麻烦一些
[/Quote]
顺便解释一下代码吧
楼主给出的
-4 - -

- - -

-8 5 - 笔算,第一步,第三行的和等于左上到右下对角线和,,-4+X=-8+5,,,得出中间的数为1,然后-4+x=1+5计算出右上角为10 进而也得出了和为3,以此类推,其它值也直接就能计算出来,,根本不用什么穷举..
基于这个考虑,写出了上面的算法的第一步,也就是通过直接推导的方式来计算幻方中其它位置的值,,如果给出的已知值不足以计算未知位置的值,就开始穷举,,
就楼主的测试数据,如果去掉其中一个,那么,我们就不可以直接计算出整个幻方了,但是,有些位置一旦有值,就可以计算出来了,可有些位置不行,本想来个"广度优先",只穷举一位来循环穷举一次,然后再穷举两位......结果想了半天,发现这样实现太困难,就改用了"深度优先",穷举完一位不成功直接穷举第二位直到穷举计算结果失败再去穷举下一位(虽然非常容易确定,这种所谓的"深度优先"算法,显然比"广度优先"效率低很多,但考虑不是什么生产环境用,也没去费事做"广度优先")
穷举的时候,穷举范围的确定比较重要,,,对于一个固定范围的穷举来说,只要给出的数据有一位超出了穷举范围,那想得到结果,怕是有些困难了,,所以这里穷举取值用了已有数据中最小值到最大值之间的范围,当然,这不可能给出所有结果但这样的取值,给出一个结果时的计算量,平均下来应该比给定范围的穷举少一些..而且分析了一下,一般来说,在这个聚会范围内,再结合直接推导法来"填写"幻方,,,,应该是可以得到结果的(当然不是全部结果)
我觉得代码最应该优化的地方就是穷举过程,如果能实现"广度优先",会快不少,特别是幻方的阶数变大时
还有取值范围,我觉得,还是应该基于现有数据来确定取值范围,不然,很可能是徒劳的
玩笑 2011-07-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 djjlove_2008 的回复:]

运行不了呀,你用的什么编译器?
[/Quote]
GCC,加参数--std=c99
因为这里我用了"变长数组"这东西,为也方便传递数组参数,不用也可以,只是写起来会麻烦一些
hack_jun 2011-07-29
  • 打赏
  • 举报
回复
好问题,咱菜鸟无能解答,等待高手。。。。。。。。。。。
djjlove_2008 2011-07-29
  • 打赏
  • 举报
回复
运行不了呀,你用的什么编译器?
玩笑 2011-07-22
  • 打赏
  • 举报
回复
晕,判断是否填写完整的函数写错了范围,,,,对角线计算错误,该死的
//      未命名3.c
// 我只是尝试一下

#include <stdio.h>
#include <stdbool.h>

int tx(int, int n[*]
  • , bool blg
  • [*][*]);
    void print(int, int n[*][*]);
    bool tx2(int x, int n[x][x], bool blg[x][x], bool blgs[x][x]) ;

    int main(int argc, char **argv)
    {
    int x;
    printf("输入边长:");
    scanf("%d", &x);

    int n[x][x];
    bool blg[x][x];
    bool blgs[x][x];

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    blg[i][j] = blgs[i][j] = false;
    }
    }

    printf("输入已知的值,行列值超范围结束(行 列 值):");
    int i, j, tmp;
    scanf("%d %d %d", &i, &j, &tmp);
    while(i > 0 && i <= x && j > 0 && j <= x) {
    n[i-1][j-1] = tmp;
    blg[i-1][j-1] = blgs[i-1][j-1] = true;
    scanf("%d %d %d", &i, &j, &tmp);
    }

    if(tx(x, n, blg) == 1) {
    print(x, n);
    } else if(tx(x, n, blg) == -1) {
    printf("很悲剧,无解\n");
    } else {
    printf("尝试打印一组可行的解,请耐心等待一会\n......");
    if(!tx2(x, n, blg, blgs)) printf("\n尝试失败,不保证无解,只是程序尝试的范围有限");
    }
    return 0;
    }

    bool tx2(int x, int n[x][x], bool blg[x][x], bool blgs[x][x]) {
    int min, max;
    bool b = false;
    bool flg = false;

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    if(blgs[i][j]) {
    if(b) {
    min = n[i][j] < min ? n[i][j] : min;
    max = n[i][j] > max ? n[i][j] : max;
    } else {
    min = max = n[i][j];
    b = true;
    }
    }
    }
    }
    if(!b) {
    printf("空的,所有点取同样值就行了,不用运行程序这么麻烦");
    return true;
    }

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    if(!blgs[i][j]) {
    for(int m = min; m <= max; ++m) {
    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    blg[i][j] = blgs[i][j];
    }
    }
    blg[i][j] = true;
    n[i][j] = m;

    int tmp = tx(x, n, blg);
    if(1 == tmp) {
    flg = true;
    print(x, n);
    } else if(0 == tmp) {
    blgs[i][j] = true;
    tx2(x, n, blg, blgs);
    blgs[i][j] = false;
    }

    }
    blg[i][j] = false;
    }
    }
    }
    return flg;
    }

    void print(int x, int n[x][x]) {
    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    printf("%d\t", n[i][j]);
    }
    printf("\n");
    }
    printf("\n");
    }

    bool pd(int x, bool blg[x][x]) {
    bool bl = true;
    for(int i = 0; bl && i < x; ++i) {
    for(int j = 0; bl && j < x; ++j) {
    bl = bl && blg[i][j];
    }
    }
    return bl;
    }

    long tj(int x, int n[x][x], int i, int j, int ii, int jj) {
    long m = 0;
    for(; i < x && j < x; i += ii, j += jj) {
    m += n[i][j];
    }
    return m;
    }


    int nul(int x, bool blg[x][x], int i, int j, int ii, int jj) {
    int n = 0;
    for(; i < x && j < x; i += ii, j += jj) {
    n += (blg[i][j] ? 0 : 1);
    }
    return n;
    }

    void tx1(int x, int n[x][x], bool blg[x][x], int i, int j, int ii, int jj, int v, int h, long tmp) {
    int k, l;
    for(; i < x && j < x; i += ii, j += jj) {
    if(!blg[i][j] && (!(i == v && j == h))) {
    k = i;
    l = j;
    }
    tmp -= n[i][j];
    }
    n[k][l] += tmp;
    blg[k][l] = true;
    }

    int tx(int x, int n[x][x], bool blg[x][x]) {
    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    long tmp;
    bool fl = false;
    if(nul(x, blg, i, 0, 0, 1) - (blg[i][j] ? 0 : 1) == 0) {
    fl = true;
    tmp = tj(x, n, i, 0, 0, 1);
    }
    if(nul(x, blg, 0, j, 1, 0) - (blg[i][j] ? 0 : 1) == 0) {
    long tmp2 = tj(x, n, 0, j, 1, 0);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }
    if(i == j) {
    if(nul(x, blg, 0, 0, 1, 1) - (blg[i][j] ? 0 : 1) == 0) {
    int tmp2 = tj(x, n, 0, 0, 1, 1);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }
    }
    if(i == x-1-j) {
    if(nul(x, blg, 0, x-1, 1, -1) - (blg[i][j] ? 0 : 1) == 0) {
    int tmp2 = tj(x, n, 0, x-1, 1, -1);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }
    }

    if(fl) {
    bool flg = false;
    if(nul(x, blg, i, 0, 0, 1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, i, 0, 0, 1, i, j, tmp);
    flg = true;
    }
    if(nul(x, blg, 0, j, 1, 0) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, j, 1, 0, i, j, tmp);
    flg = true;
    }
    if(i == j && nul(x, blg, 0, 0, 1, 1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, 0, 1, 1, i, j, tmp);
    flg = true;
    }
    if(i == x-1-j && nul(x, blg, 0, x-1, 1, -1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, x-1, 1, -1, i, j, tmp);
    flg = true;
    }
    if(flg) return tx(x, n, blg);
    }

    }
    }
    return pd(x, blg) ? 1 : 0;
    }
玩笑 2011-07-22
  • 打赏
  • 举报
回复
[arch@myhost ~]$ ./未命名3
输入边长:3
输入已知的值,行列值超范围结束(行 列 值):1 1 -4
3 1 -8
3 2 5
0 0 0
-4 -3 10
15 1 -13
-8 5 6

[arch@myhost ~]$
玩笑 2011-07-22
  • 打赏
  • 举报
回复
楼主给出的条件生成的"幻方",应该是唯一的
//      未命名3.c
// 我只是尝试一下

#include <stdio.h>
#include <stdbool.h>

int tx(int, int n[*]
  • , bool blg
  • [*][*]);
    void print(int, int n[*][*]);
    bool tx2(int x, int n[x][x], bool blg[x][x], bool blgs[x][x]) ;

    int main(int argc, char **argv)
    {
    //int n[3][3] = {[0][0] = -4, [1][1] = -3, [2][1] = 5};
    //bool blg[3][3] = {[0][0] = true, /*[1][1] = true,*/ [2][1] = true};
    //bool blgs[3][3] = {[0][0] = true, /*[1][1] = true,*/ [2][1] = true};

    int x;
    printf("输入边长:");
    scanf("%d", &x);

    int n[x][x];
    bool blg[x][x];
    bool blgs[x][x];

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    blg[i][j] = blgs[i][j] = false;
    }
    }

    printf("输入已知的值,行列值超范围结束(行 列 值):");
    int i, j, tmp;
    scanf("%d %d %d", &i, &j, &tmp);
    while(i > 0 && i <= x && j > 0 && j <= x) {
    n[i-1][j-1] = tmp;
    blg[i-1][j-1] = blgs[i-1][j-1] = true;
    scanf("%d %d %d", &i, &j, &tmp);
    }

    if(tx(x, n, blg) == 1) {
    print(x, n);
    } else if(tx(x, n, blg) == -1) {
    printf("很悲剧,无解\n");
    } else {
    printf("尝试打印一组可行的解,请耐心等待一会\n......");
    if(!tx2(x, n, blg, blgs)) printf("\n尝试失败,不保证无解,只是程序尝试的范围有限");
    }
    return 0;
    }

    bool tx2(int x, int n[x][x], bool blg[x][x], bool blgs[x][x]) {
    int min, max;
    bool b = false;
    bool flg = false;

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    blg[i][j] = blgs[i][j];
    }
    }

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    if(blg[i][j]) {
    if(b) {
    min = n[i][j] < min ? n[i][j] : min;
    max = n[i][j] > max ? n[i][j] : max;
    } else {
    min = max = n[i][j];
    b = true;
    }
    }
    }
    }
    if(!b) {
    printf("空的,所有点取同样值就行了,不用运行程序这么麻烦");
    return true;
    }

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    if(!blg[i][j]) {
    //blg[i][j] = true;
    for(int m = min; m <= max; ++m) {
    blg[i][j] = true;
    n[i][j] = m;

    int tmp = tx(x, n, blg);

    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    blg[i][j] = blgs[i][j];
    }
    }

    if(1 == tmp) {
    //printf("\n行,列,值 %d\t%d\t%d\n", i, j, m);
    flg = true;
    print(x, n);
    } else if(0 == tmp) {
    blgs[i][j] = true;
    tx2(x, n, blg, blgs);
    blgs[i][j] = false;
    }
    }
    blg[i][j] = false;
    }
    }
    }
    return flg;
    }


    void print(int x, int n[x][x]) {
    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    printf("%d\t", n[i][j]);
    }
    printf("\n");
    }
    printf("\n");
    }


    bool pd(int x, bool blg[x][x]) {
    bool bl = true;
    for(int i = 0; bl && i < 3; ++i) {
    for(int j = 0; bl && j < 3; ++j) {
    bl = bl && blg[i][j];
    }
    }
    return bl;
    }

    long tj(int x, int n[x][x], int i, int j, int ii, int jj) {
    long m = 0;
    for(; i < x && j < x; i += ii, j += jj) {
    m += n[i][j];
    }
    return m;
    }


    int nul(int x, bool blg[x][x], int i, int j, int ii, int jj) {
    int n = 0;
    for(; i < x && j < x; i += ii, j += jj) {
    n += (blg[i][j] ? 0 : 1);
    }
    return n;
    }

    void tx1(int x, int n[x][x], bool blg[x][x], int i, int j, int ii, int jj, int v, int h, long tmp) {
    int k, l;
    for(; i < x && j < x; i += ii, j += jj) {
    if(!blg[i][j] && (!(i == v && j == h))) {
    k = i;
    l = j;
    }
    tmp -= n[i][j];
    }
    n[k][l] += tmp;
    blg[k][l] = true;
    }


    int tx(int x, int n[x][x], bool blg[x][x]) {
    for(int i = 0; i < x; ++i) {
    for(int j = 0; j < x; ++j) {
    long tmp;
    bool fl = false;
    if(nul(x, blg, i, 0, 0, 1) - (blg[i][j] ? 0 : 1) == 0) {
    fl = true;
    tmp = tj(x, n, i, 0, 0, 1);
    }
    if(nul(x, blg, 0, j, 1, 0) - (blg[i][j] ? 0 : 1) == 0) {
    long tmp2 = tj(x, n, 0, j, 1, 0);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }
    if(i == j) {
    if(nul(x, blg, 0, 0, 1, 1) - (blg[i][j] ? 0 : 1) == 0) {
    int tmp2 = tj(x, n, 0, 0, 1, 1);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }

    }
    if(i == -j) {
    if(nul(x, blg, 0, x-1, 1, -1) - (blg[i][j] ? 0 : 1) == 0) {
    int tmp2 = tj(x, n, 0, x-1, 1, -1);
    if(fl && (tmp != tmp2)) {
    return -1;
    }
    fl = true;
    tmp = tmp2;
    }
    }

    if(fl) {
    bool flg = false;
    if(nul(x, blg, i, 0, 0, 1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, i, 0, 0, 1, i, j, tmp);
    flg = true;
    }
    if(nul(x, blg, 0, j, 1, 0) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, j, 1, 0, i, j, tmp);
    flg = true;
    }
    if(i == j && nul(x, blg, 0, 0, 1, 1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, 0, 1, 1, i, j, tmp);
    flg = true;
    }
    if(i == -j && nul(x, blg, 0, x-1, 1, -1) - (blg[i][j] ? 0 : 1) == 1) {
    tx1(x, n, blg, 0, x-1, 1, -1, i, j, tmp);
    flg = true;
    }
    if(flg) return tx(x, n, blg);
    }

    }
    }
    return pd(x, blg) ? 1 : 0;
    }
Jxiaoshen 2011-07-20
  • 打赏
  • 举报
回复
顶顶~~
xjmlj2010 2011-07-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gongjianmaliang 的回复:]
这找到一组答案,一个一个试探
#include <stdio.h>
int a[3][3];

int insert(int sum){
a[0][0]=-4;
a[2][0]=-8;
a[2][1]=5;
a[1][0]=sum+4+8;
a[2][2]=sum+8-5;
a[1][1]=sum-a[0][0]-a[2][2];
a[1][2]=sum-a[1][0]-a[……
[/Quote]
ko
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hdxu8511 的回复:]

C/C++ code
#include <stdio.h>

int str[9]={-4,0,0,
0,0,0,
-8,5,0};
int b[1000][9]; //保存符合条件的数据

bool judge(int a[])
{
bool jj = true;
// 横向
if( (a[0]+a[1]+a[2] ……
[/Quote]

我觉得这样已经解决问了吧?整数是无限的。。。你不如#define 个MAX,更容易更改范围
至善者善之敌 2011-07-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hdxu8511 的回复:]
C/C++ code
#include <stdio.h>

int str[9]={-4,0,0,
0,0,0,
-8,5,0};
int b[1000][9]; //保存符合条件的数据

bool judge(int a[])
{
bool jj = true;
// 横向
if( (a[0]+……
[/Quote]

帮顶吧,正在恶补数据结构。。。
djjlove_2008 2011-07-18
  • 打赏
  • 举报
回复
谢谢你们,你们都是未来的IT人才,呵呵。
gongjianmaliang 2011-07-17
  • 打赏
  • 举报
回复
这找到一组答案,一个一个试探
#include <stdio.h>
int a[3][3];

int insert(int sum){
a[0][0]=-4;
a[2][0]=-8;
a[2][1]=5;
a[1][0]=sum+4+8;
a[2][2]=sum+8-5;
a[1][1]=sum-a[0][0]-a[2][2];
a[1][2]=sum-a[1][0]-a[1][1];
a[0][1]=sum-a[1][1]-5;
a[0][2]=sum+4-a[0][1];
if(((a[0][2]+a[1][2]+a[2][2])==sum)&&((a[0][2]+a[1][1]+a[2][0])==sum))
return 1;
else return 0;
}
void main(){
int sum;
int i,j;
for(sum=-1000;sum<1000;sum++){
if(insert(sum))
{
printf("sum=%d\n",sum);
for(i=0;i<3;i++)
for(j=0;j<3;j++)
printf("a[%d][%d]=%d ",a[i][j]);
printf("\n");
}
}
}
hdxu8511 2011-07-17
  • 打赏
  • 举报
回复
#include <stdio.h>

int str[9]={-4,0,0,
0,0,0,
-8,5,0};
int b[1000][9]; //保存符合条件的数据

bool judge(int a[])
{
bool jj = true;
// 横向
if( (a[0]+a[1]+a[2] != a[3]+a[4]+a[5] )||(a[3]+a[4]+a[5] != a[6]+a[7]+a[8]) )
{ jj =false; return jj;}

// 纵向
if( (a[6]+a[7]+a[8] != a[0]+a[3]+a[6] )||(a[0]+a[3]+a[6] != a[1]+a[4]+a[7] )||(a[1]+a[4]+a[7] != a[2]+a[5]+a[8]))
{ jj =false; return jj;}

//斜向
if( (a[2]+a[5]+a[8] != a[0]+a[4]+a[8])||(a[0]+a[4]+a[8] != a[2]+a[4]+a[6]))
{ jj =false; return jj;}
return jj;

}
void main()
{
int key = str[3]; //因为分析这个矩阵会发现,当str[3]确定后,事实上满足条件的矩阵已经确定,所以只需要遍历str[3]在整数范围。
int k=0;
for(key =-1000000;key<=1000000;key++)
{
str[3] = key;
str[8] = (-4+key-8)+8-5;
str[4] = (-4+key-8)+4-str[8];
str[1] = (-4+key-8)-str[4]-5;
str[2] = (-4+key-8)+8-str[4];
str[5] = (-4+key-8)-str[3]-str[4];

if(judge(str)){
for(int i=0;i<9;i++)
{
b[k][i] = str[i];
}
k++;
}
}

// 打印数据
for(int i=0;i<k;i++)
{ for(int j=0;j<9;j++)
{
printf("%d\t",b[i][j]);
if((j+1)%3 == 0)
printf("\n");
}
}
}


我想我还没有回答楼主的问题,因为这个问题的实质是怎么解决整数范围内的表示。。 我想应该把key的整数范围用数组表示,然后进行加减,但是这个数组又要定义成多长了。。。 整数是一个无限域的。。

我只能想到这么多了 。。。 好问题 。。 期待高手解决。。。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧