CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

***一个矩阵连乘的问题***

楼主donghaish(roland)2006-06-04 15:21:50 在 C/C++ / C语言 提问

给定n个矩阵{A1,A2,...,An},考察这n个矩阵的连乘积A1A2...An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序,这种计算次序可以用加括号的方式来确定。    
   
  矩阵连乘积的计算次序与其计算量有密切关系。例如,考察计算3个矩阵{A1,A2,A3}连乘积的例子。设这3个矩阵的维数分别为10*100,100*5,和5*50。若按(A1A2)A3计算,3个矩阵连乘积需要的数乘次数为10*100*5+10*5*50   =   7500。若按A1(A2A3)计算,则总共需要100*5*50+10*100*50   =   75000次数乘。    
   
  现在你的任务是对于一个确定的矩阵连乘方案,计算其需要的数乘次数。    
   
  输入输出格式  
   
  输入数据由多组数据组成。每组数据格式如下:  
  第一行是一个整数n   (1≤n≤26),表示矩阵的个数。  
  接下来n行,每行有一个大写字母,表示矩阵的名字,后面有两个整数a,b,分别表示该矩阵的行数和列数,其中1<a,b<100。  
  第n+1行是一个矩阵连乘的表达式,由括号与大写字母组成,没有乘号与多余的空格。如果表达式中没有括号则按照从左到右的顺序计算,输入的括号保证能够配对。  
   
  对于每组数据,输出仅一行包含一个整数,即将该矩阵连乘方案需要的数乘次数。如果运算过程中出现不满足矩阵乘法法则的情况(即左矩阵列数与右矩阵的行数不同),则输出“error”。    
  样例输入  
   
  3  
  A   10   100  
  B   100   5  
  C   5   50  
  A(BC)  
   
  样例输出  
   
  75000  
   
   
  我写了一个程序,通过了我自己的所有测试数据,但是就是无法AC.请大家帮帮忙了  
  #include   <stdio.h>  
  #include   <stdlib.h>  
  #include   <string.h>  
   
  /*  
  -1:the   bottom   of   stack  
  -2:'('  
  -3:')'  
  */  
  #define   NUM_OF_CHAR 26  
  typedef   enum   {FALSE,TRUE}   BOOL;  
  struct   m{  
  int   row;  
  int   col;  
  };  
  struct   stack{  
  struct   m   a[NUM_OF_CHAR];  
  int   top;  
  };  
   
  void   initst(struct   stack   *ps)  
  {  
  ps->top=-1;  
  }  
   
  BOOL   st_empty(struct   stack   s)  
  {  
  if(s.top==-1)   return   TRUE;  
  else   return   FALSE;  
  }  
  void   push(struct   stack   *ps,struct   m   e)  
  {  
  if(ps->top+1==100){  
  printf("error:stack   is   full!\n");  
  exit(EXIT_FAILURE);  
  }  
  ps->a[++(ps->top)]=e;  
  }  
   
  struct   m   pop(struct   stack   *ps)  
  {  
  struct   m   e;  
  if(ps->top==-1){  
  printf("error:stack   is   empty!\n");  
  exit(EXIT_FAILURE);  
  }  
  e=ps->a[(ps->top)--];  
  return   e;  
  }  
  struct   m   gettop(struct   stack   *ps)  
  {  
  struct   m   e;  
  e=ps->a[ps->top];  
  return   e;  
  }  
   
  int   find(char   c[],char   ch)  
  {  
  int   i;  
  for(i=0;i<NUM_OF_CHAR;i++)  
  if(c[i]==ch)   return   i;  
  return   -1;  
  }  
   
  int   main()  
  {  
  int   i,j,n;  
  long   int   mul;  
  struct   m   mt[NUM_OF_CHAR],m[NUM_OF_CHAR],mm,e;  
  char   c[NUM_OF_CHAR];  
  char   s[100],*ps;  
  struct   stack   st;  
  BOOL   err;  
  while(scanf("%d",&n)!=EOF)  
  {  
  fflush(stdin);  
  for(i=0;i<n;i++){  
  scanf("%c%d%d",&c[i],&mt[i].row,&mt[i].col);  
  fflush(stdin);  
  }  
  gets(s);  
  ps=s;  
  initst(&st);  
  e.col=e.row=-1;  
  push(&st,e);  
  err=FALSE;  
  mul=0;  
  do  
  {  
  if(*ps>='A'&&*ps<='Z')  
  push(&st,mt[find(c,*ps)]);  
  else   if(*ps=='('){  
  e.col=-2;e.row=-2;  
  push(&st,e);  
  }  
  else   if(*ps==')'){  
  i=0;  
  m[i]=pop(&st);  
  while(m[i].row!=-2){  
  i++;  
  m[i]=pop(&st);  
  }  
  mm=m[i-1];  
  for(j=i-1;j>0;j--)  
  {  
  if(mm.col!=m[j-1].row){  
  err=TRUE;  
  break;  
  }  
  mul+=(long   int)mm.row*mm.col*m[j-1].col;  
  mm.row=mm.row;mm.col=m[j-1].col;  
  }  
  push(&st,mm);  
  if(err)   break;  
  }  
  else   if(*ps=='\0'){  
  i=0;  
  m[i]=pop(&st);  
  while(m[i].row!=-1){  
  i++;  
  m[i]=pop(&st);  
  }  
  mm=m[i-1];  
  for(j=i-1;j>0;j--)  
  {  
  if(mm.col!=m[j-1].row){  
  err=TRUE;  
  break;  
  }  
  mul+=(long   int)mm.row*mm.col*m[j-1].col;  
  mm.row=mm.row;mm.col=m[j-1].col;  
  }  
  //push(&st,mm);  
  if(err)   break;  
  }  
  ps++;  
  }while(!st_empty(st));  
  if(err)  
  printf("error\n");  
  else  
  printf("%ld\n",mul);  
   
  }  
  return   0;  
  }  
  问题点数:100、回复次数:23Top

1 楼UPCC(杂食动物)回复于 2006-06-04 18:02:22 得分 0

留个脚印...   ...Top

2 楼chenhu_doc(^0^纯一狼^0^ 看书看到大笑,直到不能自已)回复于 2006-06-04 18:13:44 得分 0

我也来做做!Top

3 楼donghaish(roland)回复于 2006-06-04 21:03:28 得分 0

up  
  Top

4 楼tailzhou(尾巴)回复于 2006-06-05 09:59:50 得分 0

你程序的输出应该有问题。  
  将  
  while(scanf("%d",&n)!=EOF)  
  {  
   
  }    
   
  修改为   scanf("%d",&n)再提交看看;  
   
  另外象   int   find(char   c[],char   ch)这个函数是没必要的,  
  struct   m   mt[NUM_OF_CHAR];  
  scanf("%c   %d   %d",&c,&row,&col);  
  mt[c-'A'].row=row;  
  mt[c-'A'].col=col;  
   
  直接使用mt[*ps-'A']就找到对应的struct   m了;  
   
  Top

5 楼tailzhou(尾巴)回复于 2006-06-05 10:10:28 得分 0

 
  原题在哪?Top

6 楼SamuelKevin(曼陀罗)回复于 2006-06-05 12:08:18 得分 0

 
  将  
  while(scanf("%d",&n)!=EOF)  
  {  
   
  }    
   
  修改为   scanf("%d",&n)再提交看看;  
   
  //楼上的   别误导人家  
  楼主那样写明明就是正确的嘛Top

7 楼tailzhou(尾巴)回复于 2006-06-05 12:14:46 得分 0

输入数据由多组数据组成。每组数据格式如下:  
  没看到这行,sorry   allTop

8 楼donghaish(roland)回复于 2006-06-05 12:51:38 得分 0

另外象   int   find(char   c[],char   ch)这个函数是没必要的,  
  struct   m   mt[NUM_OF_CHAR];  
  scanf("%c   %d   %d",&c,&row,&col);  
  mt[c-'A'].row=row;  
  mt[c-'A'].col=col;  
   
  直接使用mt[*ps-'A']就找到对应的struct   m  
   
  但是如果我输入的不按照字母顺讯,比如Z   A   E什么的按你说的就不对了Top

9 楼donghaish(roland)回复于 2006-06-05 13:03:15 得分 0

原题在acm.fzu.edu.cnTop

10 楼tailzhou(尾巴)回复于 2006-06-05 13:09:44 得分 0

没仔细看你的程序,不过测试你的程序对(a)((b))(c)这样的出不来结果,应该出入栈有问题  
   
  我写了个,我这上不了acm.fzu.edu.cn,没法测试:  
  #include   <iostream>  
   
  #define   NUM_OF_CHAR 26  
  #define   NUM_OF_STRING 100  
   
  struct   m{  
  int   row;  
  int   col;  
  };  
   
  struct   m   mt[NUM_OF_CHAR];  
  char   s[NUM_OF_STRING];  
  char   *   ps;  
  long   mul;  
   
  struct   m   multiple()  
  {  
  long   l=0;  
  struct   m   rst;  
  rst.row=0;  
  rst.col=0;  
  bool   IsFirst=true;  
  while(true)  
  {  
  if   (*ps==')'   ||   *ps=='\0')  
  {  
  if   (*ps==')')  
  {  
  ++ps;  
  }  
  return   rst;  
  }  
   
  struct   m   t;  
  if   (*ps=='(')  
  {  
  ++ps;  
  t=multiple();  
  if   (t.row==-1)  
  {  
  return   t;  
  }  
  }  
  else  
  {  
  t=mt[*ps-'A'];  
  ++ps;  
  }  
   
  if   (IsFirst)  
  {  
  rst.row=t.row;  
  rst.col=t.col;  
  IsFirst=false;  
  }  
  else  
  {  
  if   (rst.col!=t.row)  
  {  
  t.row=-1;  
  return   t;  
  }  
   
  mul+=rst.row*rst.col*t.col;  
  rst.col=t.col;  
  }  
  }  
  }  
   
   
  int   main()  
  {  
  int   i,j,n,row,col;  
  char   c;  
  scanf("%d\n",&n);  
   
  for(i=0;i<n;i++){  
  scanf("%c   %d   %d\n",&c,&row,&col);  
  mt[c-'A'].row=row;  
  mt[c-'A'].col=col;  
  }  
  gets(s);  
  ps=s;  
  mul=0;  
  struct   m   rst=multiple();  
   
  if(rst.row==-1)  
  {  
  printf("error\n");  
  }  
  else  
  {  
  printf("%ld\n",mul);  
  }  
  return   0;  
  }  
   
   
  Top

11 楼tailzhou(尾巴)回复于 2006-06-05 13:14:39 得分 0

但是如果我输入的不按照字母顺讯,比如Z   A   E什么的按你说的就不对了  
   
  这题跟输入顺序没关系的呀!Top

12 楼tailzhou(尾巴)回复于 2006-06-05 13:15:42 得分 0

D:\projects\cl>TEST  
  3  
  A   10   100  
  B   100   5  
  C   5   50  
  ((A))((B))(C)  
  7500  
   
  D:\projects\cl>TEST  
  3  
  A   10   100  
  C   5   50  
  B   100   5  
  ((A))((B))(C)  
  7500Top

13 楼donghaish(roland)回复于 2006-06-05 13:36:01 得分 0

WRONG   ANSER!Top

14 楼tailzhou(尾巴)回复于 2006-06-05 13:52:08 得分 0

我的程序只算一组数据的,你加上  
  while(scanf("%d",&n)!=EOF)  
  {  
   
  }    
  了没?Top

15 楼donghaish(roland)回复于 2006-06-05 16:31:01 得分 0

"仔细看你的程序,不过测试你的程序对(a)((b))(c)这样的出不来结果,应该出入栈有问题"  
   
  没问题啊,我试过了Top

16 楼tailzhou(尾巴)回复于 2006-06-05 16:41:36 得分 0

帖子你肯定修改过了,  
  #define   NUM_OF_CHAR26,  
  上午都还能编译通过的Top

17 楼donghaish(roland)回复于 2006-06-05 17:14:36 得分 0

大哥,冤枉,我还不知道怎么修改帖子呢?!  
  我一点都没改Top

18 楼donghaish(roland)回复于 2006-06-06 23:37:58 得分 0

upTop

19 楼donghaish(roland)回复于 2006-06-10 22:04:09 得分 0

UPTop

20 楼tailzhou(尾巴)回复于 2006-06-12 19:57:54 得分 0

30559   2006-06-12   19:54:44   Accepted   1061   C++   0.00s   320K   tailzhou    
   
  #include   <iostream>  
   
  #define   NUM_OF_CHAR   26  
  #define   NUM_OF_STRING   500  
   
  struct   m{  
  int   row;  
  int   col;  
  };  
   
  struct   m   mt[NUM_OF_CHAR];  
  char   s[NUM_OF_STRING];  
  char   *   ps;  
  long   mul;  
   
  struct   m   multiple()  
  {  
  long   l=0;  
  struct   m   rst;  
  rst.row=0;  
  rst.col=0;  
  bool   IsFirst=true;  
  while(true)  
  {  
  if   (*ps==')'   ||   *ps=='\0')  
  {  
  if   (*ps==')')  
  {  
  ++ps;  
  }  
  return   rst;  
  }  
   
  struct   m   t;  
  if   (*ps=='(')  
  {  
  ++ps;  
  t=multiple();  
  if   (t.row==-1)  
  {  
  return   t;  
  }  
  }  
  else  
  {  
  t=mt[*ps-'A'];  
  ++ps;  
  }  
   
  if   (IsFirst)  
  {  
  rst.row=t.row;  
  rst.col=t.col;  
  IsFirst=false;  
  }  
  else  
  {  
  if   (rst.col!=t.row)  
  {  
  t.row=-1;  
  return   t;  
  }  
   
  mul+=rst.row*rst.col*t.col;  
  rst.col=t.col;  
  }  
  }  
  }  
   
   
  int   main()  
  {  
  int   i,j,n,row,col;  
  char   c;  
  while(scanf("%d\n",&n)!=EOF)  
  {  
   
  for(i=0;i<n;i++){  
  scanf("%c   %d   %d\n",&c,&row,&col);  
  mt[c-'A'].row=row;  
  mt[c-'A'].col=col;  
  }  
  gets(s);  
  ps=s;  
  mul=0;  
  struct   m   rst=multiple();  
   
  if(rst.row==-1)  
  {  
  printf("error\n");  
  }  
  else  
  {  
  printf("%ld\n",mul);  
  }  
  }  
  return   0;  
  }  
  Top

21 楼tailzhou(尾巴)回复于 2006-06-12 20:06:04 得分 0

30561   2006-06-12   19:58:58   Accepted   1061   C++   0.01s   180K   tailzhou    
  这次是用的你的程序(几处小修改)  
   
  #include   <stdio.h>  
  #include   <stdlib.h>  
  #include   <string.h>  
   
  /*  
  -1:the   bottom   of   stack  
  -2:'('  
  -3:')'  
  */  
  #define   NUM_OF_CHAR   26   //*****   修改NUM_OF_CHAR26-->   NUM_OF_CHAR   26  
  typedef   enum   {FALSE,TRUE}   BOOL;  
  struct   m{  
  int   row;  
  int   col;  
  };  
  struct   stack{  
  struct   m   a[NUM_OF_CHAR];  
  int   top;  
  };  
   
  void   initst(struct   stack   *ps)  
  {  
  ps->top=-1;  
  }  
   
  BOOL   st_empty(struct   stack   s)  
  {  
  if(s.top==-1)   return   TRUE;  
  else   return   FALSE;  
  }  
  void   push(struct   stack   *ps,struct   m   e)  
  {  
  if(ps->top+1==500){           //*******修改   100-->500  
  printf("error:stack   is   full!\n");  
  exit(EXIT_FAILURE);  
  }  
  ps->a[++(ps->top)]=e;  
  }  
   
  struct   m   pop(struct   stack   *ps)  
  {  
  struct   m   e;  
  if(ps->top==-1){  
  printf("error:stack   is   empty!\n");  
  exit(EXIT_FAILURE);  
  }  
  e=ps->a[(ps->top)--];  
  return   e;  
  }  
  struct   m   gettop(struct   stack   *ps)  
  {  
  struct   m   e;  
  e=ps->a[ps->top];  
  return   e;  
  }  
   
  int   find(char   c[],char   ch)  
  {  
  int   i;  
  for(i=0;i<NUM_OF_CHAR;i++)  
  if(c[i]==ch)   return   i;  
  return   -1;  
  }  
   
  int   main()  
  {  
  int   i,j,n;  
  long   int   mul;  
  struct   m   mt[NUM_OF_CHAR],m[NUM_OF_CHAR],mm,e;  
  char   c[NUM_OF_CHAR];  
  char   s[500],*ps;   //******   修改   s[100]-->s[500]  
  struct   stack   st;  
  BOOL   err;  
  while(scanf("%d\n",&n)!=EOF)   //**   修改"%d"-->"%d\n"  
  {  
  //fflush(stdin);         //****   注释了这行  
  for(i=0;i<n;i++){  
  scanf("%c   %d   %d\n",&c[i],&mt[i].row,&mt[i].col);   ////**   修改"("%c%d%d"-->"%c   %d   %d\n"  
  //fflush(stdin);       //****   注释了这行  
  }  
  gets(s);  
  ps=s;  
  initst(&st);  
  e.col=e.row=-1;  
  push(&st,e);  
  err=FALSE;  
  mul=0;  
  do  
  {  
  if(*ps>='A'&&*ps<='Z')  
  push(&st,mt[find(c,*ps)]);  
  else   if(*ps=='('){  
  e.col=-2;e.row=-2;  
  push(&st,e);  
  }  
  else   if(*ps==')'){  
  i=0;  
  m[i]=pop(&st);  
  while(m[i].row!=-2){  
  i++;  
  m[i]=pop(&st);  
  }  
  mm=m[i-1];  
  for(j=i-1;j>0;j--)  
  {  
  if(mm.col!=m[j-1].row){  
  err=TRUE;  
  break;  
  }  
  mul+=(long   int)mm.row*mm.col*m[j-1].col;  
  mm.row=mm.row;mm.col=m[j-1].col;  
  }  
  push(&st,mm);  
  if(err)   break;  
  }  
  else   if(*ps=='\0'){  
  i=0;  
  m[i]=pop(&st);  
  while(m[i].row!=-1){  
  i++;  
  m[i]=pop(&st);  
  }  
  mm=m[i-1];  
  for(j=i-1;j>0;j--)  
  {  
  if(mm.col!=m[j-1].row){  
  err=TRUE;  
  break;  
  }  
  mul+=(long   int)mm.row*mm.col*m[j-1].col;  
  mm.row=mm.row;mm.col=m[j-1].col;  
  }  
  //push(&st,mm);  
  if(err)   break;  
  }  
  ps++;  
  }while(!st_empty(st));  
  if(err)  
  printf("error\n");  
  else  
  printf("%ld\n",mul);  
   
  }  
  return   0;  
  }  
   
   
  Top

22 楼nanangerile(闲)回复于 2006-06-13 00:07:10 得分 0

upTop

23 楼softj(天地客人<最近很迷茫>)回复于 2006-06-14 16:00:14 得分 0

有意思,UPTop

相关问题

关键词

得分解答快速导航

  • 帖主:donghaish

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo