【问题标题】:Find maximum users in a cell of a matrix of size nxn在大小为 nxn 的矩阵的单元中查找最大用户
【发布时间】:2015-06-21 04:40:24
【问题描述】:

我正在解决这个算法问题,但我无法找到提供的参考答案。感谢您提供解决此问题的任何帮助或提示。

问题陈述如下 在大小为 NxN 的区域中,每个单元格在 T=0 时包含 1,其中 1 代表一个用户。

Hence, at T= 0 and N = 5 the matrix is as below
1   1   1   1   1
1   1   1   1   1
1   1   1   1   1
1   1   1   1   1
1   1   1   1   1
Each cell is a user.
Now at time T =1,2,3 etc the position of each user changes.

if x(row)+y(col) = even
New x = (x+y)^2%N
New y = (x*y)%N

if x(row)+y(col) = odd
New x = (x+y)%N
New y = |x-y|%N

在时间 T = 3 找到最大用户 参考,对于 N=5 和 T=3 单元格中的最大用户数应为 8。

我已尝试解决此问题,但如果我移动所有用户,我总是以 11 作为我的最大值,如果我每次只移动 1 个用户,我总是以 6 作为我的最大值。 非常感谢我在理解或解决此问题时可能出错的任何提示。谢谢你。 下面是我用来解决这个问题的代码 它在 C 编程语言中。提前致谢。

int abs(int y, int x)
    {
     int temp = x - y;
     return temp > 0 ? temp : -temp;
    }

int new_x(int x, int y, int n)
{
 if((x+y)%2)
  return (((x+y)*(x+y))%n);
 else
  return (x+y)%n;
}

int new_y(int x, int y, int n)
{
 if((x+y)%2)
  return (x*y)%n;
 else
  return ((abs(x,y))%n);

}

void print_matrix(int *p, int n, int time)
{
    int i,j;
    int sum = 0;
    for(i=0;i<n;i++) {
        for(j=0;j<n;j++) {
            printf("%d\t",*((p+i*n)+j));
            sum += *((p+i*n)+j);
        }
    printf("\n");
    }
    printf("Sum = %d\t at T=%d\n",sum, time);
}


int main(void)
{
    int T = 3;
    int N = 5;
    int test_case,i,j,x,y,item, sum, val;
    int arr_initial[5][5];
    //====================================
    //For Time T=0 all elements are 1
    //====================================
    for(i=0;i<N;i++){
            for(j=0;j<N;j++) {
                arr_initial[i][j] = 1;
            }
        }
        //=====================================
        printf("Initial Matrix at T0 time\n");
        print_matrix((int*)arr_initial, N, 0);
        printf("\n");
        //====================================
        //Now calculate the new position for Time T1,T2 & T3
        //====================================
        for(test_case =1; test_case<=T;test_case++)
        {
            sum = 0;
            for(i=0;i<N;i++)
            {
                for(j=0;j<N;j++)
                {//Get NewX and NewY for movement
                    x = new_x(i,j,N);
                    y = new_y(i,j,N);
                    if(x==i && y==j)
                        {
                        //No movement as initial and new position is same
                        }
                    else{
                        //There is a movement
                        item = arr_initial[i][j];
                        val = item -1;
                            if(val<0) 
                                {
                                //no item to move
                                }
                            else 
                                {
                                arr_initial[x][y] += arr_initial[i][j];
                                arr_initial[i][j] = 0;
                                }
                        }

                    }
                }
            //=======================================================
            printf("\n");
            printf("Matrix at Time T = %d\n",test_case);
            print_matrix((int*)arr_initial, N, test_case);
            printf("\n");
            }
    return 0;   
}

【问题讨论】:

  • if((x+y)%2)x+y 为奇数时为真
  • N 和 M 的约束是什么?问题是当你更新用户位置时,你直接将它更新到同一个数组,所以,你可以在读取和处理之前修改一个单元格,这会导致错误的答案。
  • 您好,感谢您指出错误。 N 的限制是 5

标签: c arrays algorithm multidimensional-array


【解决方案1】:

您的任务语句与代码不同 - 您说的是 (x*y)^2,但实现了 (x+y)^2。该解决方案通过在单独的数组中构建下一代来工作。

#include <stdio.h>
#include <string.h>
#include <math.h>

#define N 5

int main(void) {
    char matrix[N][N], next[N][N];
    int x, y, t, x2, y2, max;
    memset(matrix, 1, sizeof(matrix));          // initialise matrix
    for(t=0; t<3; t++) {
        memset(next, 0, sizeof(next));          // clear next generation
        for (y=0; y<N; y++)
            for (x=0; x<N; x++) {
                if ((x + y) % 2 == 0) {
                    x2 = ((x + y) * (x + y)) % N;
                    y2 = (x * y) % N;
                } else {
                    x2 = (x + y) % N;
                    y2 = abs(x - y) % N;
                }
                next[y2][x2] += matrix[y][x];
            }
        memcpy(matrix, next, sizeof(matrix));   // copy back
    }

    max = 0;
    for (y=0; y<N; y++) {                       // print matrix
        for (x=0; x<N; x++) {
            if (max < matrix[y][x])
                max = matrix[y][x];
            printf("%-3d", matrix[y][x]);
        }
        printf ("\n");
    }
    printf ("Max is %d\n", max);
    return 0;
}

程序输出:

1  0  0  0  0
0  2  0  0  4
0  0  0  0  0
4  8  0  4  0
0  2  0  0  0
Max is 8

【讨论】:

    【解决方案2】:

    问题是您正在从数组中读取值,并且该值可能已经被修改,成为 T + 1 的值!

    因此,您需要另一个数组来跟踪 T 的值。想法如下:

        for(i = 0; i < N; i ++)
            for (j = 0; j < N; j ++)
                alter_arr[i][j] = current_arr[i][j];
    
        for(i=0;i<N;i++)
        {
            for(j=0;j<N;j++)
            {//Get NewX and NewY for movement
                x = new_x(i,j,N);
                y = new_y(i,j,N);
    
                printf("%d, %d moved to %d, %d\n", i, j, x, y);
                if(x==i && y==j)
                {
                    // no movement
                }
                else{
                    //There is a movement
                    item = current_arr[i][j];
                    val = item -1;
                    if(val<0) 
                    {
                        //no item to move
                    }
                    else 
                    {
                        alter_arr[x][y] += current_arr[i][j];
                        alter_arr[i][j] -= current_arr[i][j];
                    }
                }
    
            }
        }
    
        int (*tmp)[5] = current_arr;
        current_arr = alter_arr;
        alter_arr = tmp;
    
        //=======================================================
        printf("\n");
        printf("Matrix at Time T = %d\n",test_case);
    

    并更改 new_x 和 new_y 函数中的 if 语句。

    以下是结果,T = 3 时最大值为 8:

    Initial Matrix at T0 time
    1   1   1   1   1   
    1   1   1   1   1   
    1   1   1   1   1   
    1   1   1   1   1   
    1   1   1   1   1   
    Sum = 25     at T=0
    
    
    Matrix at Time T = 1
    1   2   0   2   0   
    2   2   0   4   2   
    0   2   0   0   0   
    0   2   0   2   0   
    2   2   0   0   0   
    Sum = 25     at T=1
    
    
    Matrix at Time T = 2
    1   0   0   4   0   
    2   4   0   6   2   
    0   0   0   0   0   
    0   2   0   2   0   
    0   2   0   0   0   
    Sum = 25     at T=2
    
    
    Matrix at Time T = 3
    1   0   0   4   0   
    0   2   0   8   2   
    0   0   0   0   0   
    0   0   0   4   0   
    0   4   0   0   0   
    Sum = 25     at T=3
    

    【讨论】:

      【解决方案3】:

      1) 你计算 (x+y) 是否是奇数错误。如果 (x+y)%2 为真,则 x+y 为奇数。因此:

      int new_x(int x, int y, int n)
      {
       if((x+y)%2)
        return (((x+y)*(x+y))%n);
       else
        return (x+y)%n;
      }
      
      int new_y(int x, int y, int n)
      {
       if((x+y)%2)
        return (x*y)%n;
       else
        return ((abs(x,y))%n);
      
      }
      

      应该改为:

      int new_x(int x, int y, int n)
      {
       if((x+y)%2)
        return (x+y)%n;
       else
        return (((x+y)*(x+y))%n);
      }
      
      int new_y(int x, int y, int n)
      {
       if((x+y)%2)
        return ((abs(x,y))%n);
       else
        return (x*y)%n;
      }
      

      2) 您更改了数组中的字段,这些字段可能仍未处理:

      arr_initial[x][y] += arr_initial[i][j];
      

      您需要使用另一个初始化为 0 的矩阵来跟踪其中的新值,并在每一步结束时将更改复制回原始矩阵。

      【讨论】:

      • 您好,感谢您指出错误,我会再试一次。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      相关资源
      最近更新 更多