wayne 发表于 2010-8-19 15:44:10

20# 没——问题

运行时错误,:Q:

没——问题 发表于 2010-8-19 16:22:20

本帖最后由 没——问题 于 2010-8-19 16:24 编辑

20# 没——问题

运行时错误,:Q:
wayne 发表于 2010-8-19 15:44 http://bbs.emath.ac.cn/images/common/back.gif

我这里正常啊(我刚才编辑帖子是改那个时间复杂度,后来发现没错,又改回去了)

难道你那里错误是因为内存消耗太大?
其时还可以优化一个数量级,当时只是顺手那么写的
这个是优化过的,并且输出全部解(上一个输出的不是全部解)/**************************************************************************
* 题目:紫罗兰算式
*      设第一个数是“CLOVER”;
*      第二个数是“CROCUS”;
*      第三个数是“VIOLET”;
*      其中第一个数与第二个数的和是第三个数,
*      注意:相同的字母表示同一个数字,不同的字母
*      表示不同的数字。每个字母的取值是从0到9的整数。
*      http://bbs.emath.ac.cn/viewthread.php?tid=2606&extra=&page=1
* 分析:
*      设所求的三个数为X,Y,Z,通过写做10的幂的和的形式可得到方程:
*      -99900*V+10*U-T+S+10001*R+1000*O+9900*L-10000*I+200100*C==0
*      分为两组:
*      -99900*V+10*U-T+S+10001*R == -1000*O-9900*L+10000*I-200100*C
*      对等式两边分别将所有可能的值写入数组left和right,并分别排序
*      数组的每个元素除存储等式一侧的值外还需存储生成此值的变元的值
*      寻找两组中相等的数,时间复杂度: 10^5+10^4
*************************************************************************/
#include <stdlib.h>
#include <stdio.h>

typedef struct {int value,id;} group;//value为等式一侧的值,id为一侧变量的值依次排列在一起组成的十进制数字的值
int cmp(const void *a, const void *b){return ((group *)a)->value - ((group *)b)->value;}//从小到大排序

int main()
{
    int o,l,i,c,r;//生成数据时vutsr和olic中只使用了5个
    group left,*pl=left,right,*pr=right;
    for(o=0;o<10;o++)for(l=0;l<10;l++)for(i=0;i<10;i++)for(c=0;c<10;c++)
    {
      pr->value=-1000*o-9900*l+10000*i-200100*c;
      pr->id=1000*o+100*l+10*i+c;
      pr++;
   for(r=0;r<10;r++)   
      {
            pl->value=-99900*o+10*l-i+c+10001*r;
            pl->id=o*10000+l*1000+i*100+c*10+r;
            pl++;
      }
    }

    qsort(left, 100000, sizeof(group), cmp);
    qsort(right, 10000, sizeof(group), cmp);

    printf("%d,%d\n",left.value,right.value);
    printf("vutsr,olic\n----------\n");
    for(pl--,pr--;pl!=left&&pr!=right;)
    {
      if(pl->value==pr->value)
      {
            //输出变元的值,此处没有排除使得X,Y,Z中出现前导零的答案.
            printf("%05d,%04d\n",pl->id,pr->id);
            while((pl-1)->value==pl->value)pl--,printf("%05d,%04d\n",pl->id,pr->id);
            while((pr-1)->value==pr->value)pr--,printf("%05d,%04d\n",pl->id,pr->id);
            pl--,pr--;
      }
      if(pl->value > pr->value)pl--;else pr--;
    }

    return 0;
}
我这里:
real        0m0.038s
user        0m0.028s
sys        0m0.004s

wayne 发表于 2010-8-19 16:47:28

real      0m0.038s
user      0m0.028s
sys      0m0.004s
莫非是在linux下用了time命令?

俺是在windows下用GCC编译的。
为啥第一个是运行时错误,第二个是输出一堆的结果呢,按道理只有一个答案的

mathe 发表于 2010-8-19 17:17:49

他没有检查两边id中使用了重复数据的情况,稍微修改即可:
/**************************************************************************
* ..:.....
*      ......聯CLOVER聰.
*      .....聯CROCUS聰.
*      .....聯VIOLET聰.
*      ...................
*      .....................
*      .................0.9....
*      http://bbs.emath.ac.cn/viewthread.php?tid=2606&extra=&page=1
* ..:
*      ........X,Y,Z,....10............:
*      -99900*V+10*U-T+S+10001*R+1000*O+9900*L-10000*I+200100*C==0
*      ....:
*      -99900*V+10*U-T+S+10001*R == -1000*O-9900*L+10000*I-200100*C
*      ..................left.right,.....
*      ..............................
*      .........,.....: 10^5+10^4
*************************************************************************/
#include <stdlib.h>
#include <stdio.h>

typedef struct {int value,id;} group;//value.......,id........................
int cmp(const void *a, const void *b){return ((group *)a)->value - ((group *)b)->value;}//......
int testid(int id1, int id2)
{
    char b;
    int i;
    for(i=0;i<10;i++)b=0;
    for(i=0;i<5;i++){
      b++;
      id1/=10;
    }
    for(i=0;i<4;i++){
       b++;
       id2/=10;
    }
    for(i=0;i<10;i++)if(b>1)return 0;
    return 1;
}

int main()
{
    int o,l,i,c,r;//.....vutsr.olic.....5.
    group left,*pl=left,right,*pr=right;
    for(o=0;o<10;o++)for(l=0;l<10;l++)for(i=0;i<10;i++)for(c=0;c<10;c++)
    {
      pr->value=-1000*o-9900*l+10000*i-200100*c;
      pr->id=1000*o+100*l+10*i+c;
      pr++;
   for(r=0;r<10;r++)   
      {
            pl->value=-99900*o+10*l-i+c+10001*r;
            pl->id=o*10000+l*1000+i*100+c*10+r;
            pl++;
      }
    }

    qsort(left, 100000, sizeof(group), cmp);
    qsort(right, 10000, sizeof(group), cmp);

    printf("%d,%d\n",left.value,right.value);
    printf("vutsr,olic\n----------\n");
    for(pl--,pr--;pl!=left&&pr!=right;)
    {
      if(pl->value==pr->value)
      {
            //......,........X,Y,Z..........
            if(testid(pl->id,pr->id))
            printf("%05d,%04d\n",pl->id,pr->id);
            while((pl-1)->value==pl->value){
            pl--;
            if(testid(pl->id,pr->id))
               printf("%05d,%04d\n",pl->id,pr->id);
            }
            while((pr-1)->value==pr->value){
                  pr--;
               if(testid(pl->id,pr->id))
                  printf("%05d,%04d\n",pl->id,pr->id);
            }
            pl--,pr--;
      }
      if(pl->value > pr->value)pl--;else pr--;
    }

    return 0;
}
输出:
-899109,-1899000
vutsr,olic
----------
59376,0842

mathe 发表于 2010-8-19 17:33:59

这个程序很简单,我给一个C++版本的:
#include <stdio.h>
#include <algorithm>
using namespace std;
#define C a
#define L a
#define O a
#define V a
#define E a
#define R a
#define U a
#define S a
#define I a
#define T a
#define NUM(x1,x2,x3,x4,x5,x6) ((x1)*100000+(x2)*10000+(x3)*1000+(x4)*100+(x5)*10+(x6))
int a={0,1,2,3,4,5,6,7,8,9};
int main()
{
    do{
         int x=NUM(C,L,O,V,E,R);
         int y=NUM(C,R,O,C,U,S);
         int z=NUM(V,I,O,L,E,T);
         if(x+y==z){
            printf(" %d\n+%d\n-------\n %d\n",x,y,z);
         }
    }while(next_permutation(a,a+10));
    return 0;
}

风云剑 发表于 2010-8-19 17:54:16

全排列函数next_permutation,真巧妙。

没——问题 发表于 2010-8-19 18:03:27

他没有检查两边id中使用了重复数据的情况,稍微修改即可:
mathe 发表于 2010-8-19 17:17 http://bbs.emath.ac.cn/images/common/back.gif

是的~,注释里的题目是复制上去的~,看来当时应该读一下~:lol
而且(假如注意到这个限制...囧),E不是任意的,只能是1
从开始我就无视了这条件...囧

显然的:
mathe的代码也是秒以下
real        0m0.345s
user        0m0.308s
sys        0m0.004s
而且省空间

mathe 发表于 2010-8-19 18:19:05

你的机器挺慢的。
不过这个题目,由于非常简单,我觉得代码的可读性比效率更加重要

没——问题 发表于 2010-8-19 18:54:30

恩,老机器了,所以装的linux
为了学习东方的算法才写这个的

wayne 发表于 2010-8-21 15:08:22

25# mathe

没想到algorithm里面竟然还有next_permutation 这个函数!!!
页: 1 2 [3] 4 5 6 7
查看完整版本: 紫罗兰算式(数学代数方面的)