标题:数塔的变形题,样例能过,交上去显示答案错误,求帮忙看一下错在哪里?
只看楼主
青蝶
Rank: 2
等 级:论坛游民
帖 子:160
专家分:51
注 册:2018-2-4
结帖率:92%
已结贴  问题点数:10 回复次数:5 
数塔的变形题,样例能过,交上去显示答案错误,求帮忙看一下错在哪里?
题意:给一个m*n的矩阵,让你用一条线 从第1行连到第m行(每行只能选一个元素),要求这条线所经过的元素之和最小。(0<m,n<=100)
有以下规定——
1,若你选择了位置(i,j)的元素,那么下一行的元素你只能选择(i+1,j-1)、(i+1,j)、(i+1,j+1)三个之一(当然边界只能选两个)。
2,若可以找到多条  路径上元素之和最小 的线,那么你要优先选择最右边的线。
3,最后从第一行开始 输出线上元素的纵坐标。

我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[105][105],s[105][105],d[105];
int min_index(int mat[],int n){      //在一维数组中找到元素最小值的下标的函数
    int i=2,m=1;
    if(n==1) return 1;
    while(mat[i]<=mat[m] && i<=n){
        m=i;
        i++;
    }
    return m;
}
   
int main(void){
    int T,m,n,i,j,k=1,index;
    scanf("%d",&T);
    while(T--){                      //多组数据输入
        scanf("%d %d",&m,&n);        //数组行数m,列数n
        for(i=1;i<=m;i++){
            for(j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
        memset(s,0,sizeof(s));
        printf("Case %d\n",k++);
        if(m==1){                              //特殊情况讨论:只有一行元素
            printf("%d\n",min_index(a[1],n));
            continue;
        }
        else if(n==1){                         //特殊情况讨论:只有一列元素
            for(i=1;i<=m;i++) printf("1%c",i!=m?' ':'\n');
            continue;
        }
        else{                                  //一般情况
         for(i=2;i<=m;i++){
            for(j=2;j<n;j++){
                if(a[i-1][j+1]<=a[i-1][j] && a[i-1][j+1]<=a[i-1][j-1]){          //纵坐标不是最头或最尾,有上一行的三个数可以选择
                    a[i][j]+=a[i-1][j+1];                                        //先计算最靠右的值是不是最小的
                    s[i][j]=j+1;                                                 //s数组用来存上一行所取元素的列数下标
                }
                else if(a[i-1][j]<=a[i-1][j+1] && a[i-1][j]<=a[i-1][j-1]){        //最靠右的值如果不是最小,看中间的值是不是最小
                    a[i][j]+=a[i-1][j];
                    s[i][j]=j;
                }
                else{                                                              //最左边的值最小,只能取最左边的值
                    a[i][j]+=a[i-1][j-1];
                    s[i][j]=j-1;
                }
            }
            if(a[i-1][2]<=a[i-1][1]){                                  //对每列第一个元素讨论,只可能取两个值(上一行中间或右边)
                a[i][1]+=a[i-1][2];
                s[i][1]=2;
            }
            else{
                a[i][1]+=a[i-1][1];
                s[i][1]=1;            
            }
            if(a[i-1][n]<=a[i-1][n-1]){                             //对每列最后一个元素讨论,只可能取两个值(上一行中间或左边)              
                a[i][n]+=a[i-1][n];
                s[i][n]=n;
            }
            else{
                a[i][n]+=a[i-1][n-1];
                s[i][n]=n-1;
            }
        }
        index=min_index(a[m],n);
        for(i=m;i>=1;i--){
            d[i]=index;                                         //把所有所选元素的列数下标存到数组d中
            index=s[i][index];
        }
        for(i=1;i<=m;i++)
            printf("%d%c",d[i],(i!=m)?' ':'\n');                //从第一行开始,输出所选元素的列数下标
    }
}
  return 0;
}
   
   
搜索更多相关主题的帖子: 元素 最小 一行 int for 
2018-06-04 13:55
lin5161678
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:45
帖 子:1136
专家分:3729
注 册:2011-12-3
得分:5 
程序代码:
int min_index(int mat[],int n){      //在一维数组中找到元素最小值的下标的函数
    int i=2,m=1;
    if(n==1) return 1;
    while(mat[i]<=mat[m] && i<=n){
        m=i;
        i++;
    }
    return m;
}

这个函数你说是找最小元素
但看实现没有达到这个目的
比如有这样的数据

4 5 1

mat[2] == 5
mat[1] == 4

mat[i]<=mat[m] <==> 5 <= 4
退出循环
return 1;
实际上最小值是 1
应该return 3

比如 你输入了
1
1 3
4 5 1
按照你的代码会输出 1
实际应该输出 3

[此贴子已经被作者于2018-6-4 14:35编辑过]


https://zh.
2018-06-04 14:29
酸奶味皮皮虾
Rank: 2
等 级:论坛游民
帖 子:28
专家分:54
注 册:2018-5-26
得分:0 
2018-06-04 22:19
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:5 
程序代码:
#include <stdio.h>

int main( void )
{
    unsigned T;
    scanf( "%u", &T );
    for( unsigned t=0; t!=T; ++t )
    {
        unsigned m, n;
        scanf( "%u%u", &m, &n );

        int matrix[100][100];
        for( unsigned r=0; r!=m; ++r )
            for( unsigned c=0; c!=n; ++c )
                scanf( "%d", &matrix[r][c] );

        for( unsigned i=m-1; i!=0; --i )
            for( unsigned c=0; c!=n; ++c )
            {
                int v = matrix[i][c];
                if( c>0 && matrix[i][c-1]<v )
                    v = matrix[i][c-1];
                if( c+1<n && matrix[i][c+1]<v )
                    v = matrix[i][c+1];
                matrix[i-1][c] += v;
            }

        unsigned c_idx = 0;
        for( unsigned c=0; c!=n; ++c )
            if( matrix[0][c] <= matrix[0][c_idx] )
                c_idx = c;
        printf( "Case %u\n", t+1 );
        printf( "%u", c_idx+1 );
        for( unsigned r=1; r!=m; ++r )
        {
            unsigned index = c_idx;
            if( c_idx>0 && matrix[r][c_idx-1]<matrix[r][index] )
                index = c_idx-1;
            if( c_idx+1<n && matrix[r][c_idx+1]<=matrix[r][index] )
                index = c_idx+1;
            c_idx = index;
            printf( " %u", c_idx+1 );
        }
        putchar( '\n' );
    }

    return 0;
}
2018-06-05 09:29
青蝶
Rank: 2
等 级:论坛游民
帖 子:160
专家分:51
注 册:2018-2-4
得分:0 
回复 2楼 lin5161678
改成:
int min_index(int mat[],int n){
    int i=2,m=1;
    if(n==1) return 1;
    while(i<=n){
        if(mat[i]<=mat[m]) m=i;
        i++;
    }
    return m;
}
   
程序过了,谢谢大佬
2018-06-05 17:48
青蝶
Rank: 2
等 级:论坛游民
帖 子:160
专家分:51
注 册:2018-2-4
得分:0 
回复 4楼 rjsp
谢谢大佬
2018-06-05 17:49



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-487591-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.451153 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved