pku 1166 the clocks 高斯消去法 解题报告

来源:互联网 发布:写医学论文的软件 编辑:程序博客网 时间:2024/04/29 19:54

 

pku 1166 the clocks 解题报告

高斯消去法的典型应用

题意:

输入提供9个钟表的位置(钟表的位置只能是0点、3点、6点、9点,分别用0123)表示。而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一、二、四、五个钟调正,如原来是0点,那么调正后为3点。问经过那些步骤可以导致9个钟的位置都在0点。

算法:

如果数学敏感度不强的话,那么此题很容易陷入bfs算法来做,时间复杂度就很大了。其实我们可以仔细观察题意的要求:

Move   Affected clocks
1         ABDE
2         ABC
3         BCEF
4         ADG
5         BDEFH
6         CFI
7         DEGH
8         GHI
9         EFHI  

影响第一个钟的就仅有124move了,同理其他也是这样,而在sample钟的第一个中只需要移动一步就可以达到0点,此时就发现了一个线性规律。我们可否将124move设置为x1,x2,x4呢?而且x1+x2+x4=1.问题看来变得很简单。我们现在尝试将所有与每个钟都相关的步骤联系起来,如下:

x1+x2+x4=1

x1+x2+x3+x5=1

x2+x3+x6=0

x1+x4+x5+x7=2

x1+x3+x5+x7+x9=2

x3+x5+x6+x9=2

x4+x7+x8=2

x5+x7+x8+x9=3

x6+x8+x9=2

output结果相比,很容易联想到x4=1,x5=1,x7=1,x8=1,其他x值都为0.经过检查,与猜想符合。那么问题就是编写高斯消去法的问题了。

AC代码:

#include<iostream>

using namespace std;

 

int move[9][9] = {

       {1, 1, 0, 1, 1, 0, 0, 0, 0},

       {1, 1, 1, 0, 0, 0, 0, 0, 0},

       {0, 1, 1, 0, 1, 1, 0, 0, 0},

       {1, 0, 0, 1, 0, 0, 1, 0, 0},

       {0, 1, 0, 1, 1, 1, 0, 1, 0},

       {0, 0, 1, 0, 0, 1, 0, 0, 1},

       {0, 0, 0, 1, 1, 0, 1, 1, 0},

       {0, 0, 0, 0, 0, 0, 1, 1, 1},

       {0, 0, 0, 0, 1, 1, 0, 1, 1}

};

int N = 9;

int f[9][9];

int ans[9], x[9];

 

int Guass()

{

       int i, j, k, temp;

       bool flag;

 

       for (i = 0; i <= N - 1; i++)

       {

              if (f[i][i] == 0)

              {

                     flag = false;

                     for (j = i + 1; j <= N - 1; j++)

                     {

                            if (f[j][i] != 0)

                            {

                                   flag = true;

                                   for (k = 0; k <= N - 1; k++)

                                   {

                                          temp = f[i][k];

                                          f[i][k] = f[j][k];

                                          f[j][k] = temp;

                                   }

                                   temp = ans[i];

                                   ans[i] = ans[j];

                                   ans[j] = temp;

                                   break;

                            }

                     }

                     if (!flag)

                     {

                            return 1;

                     }

              }

              for (j = i + 1; j <= N - 1; j++)

              {

                     if (f[j][i] != 0)

                     {

                            temp = f[j][i];

                            for (k = i; k <= N - 1; k++)

                            {

                                   f[j][k] *= f[i][i];

                                   f[j][k] -= (f[i][k] * temp);

                            }

                            ans[j] = ans[j] * f[i][i] - ans[i] * temp;

                     }

              }

       }

       for (i = N - 1; i >= 0; i--)

       {

              temp = ans[i];

              for (j = N - 1; j > i; j--)

              {

                     temp -= f[i][j] * x[j];

              }

              temp = (temp % 4 + 4) % 4;

              for (j = 0; j <= 3; j++)

              {

                     if ((j * f[i][i] % 4 + 4) % 4 == temp)

                     {

                            x[i] = j;

                     }

              }

       }

       return 0;

}

 

int main()

{

       freopen("1.txt", "r", stdin);

       int i, j;

       int clocks[9];

 

       for (i = 0; i < N; i++)

       {

              cin >> clocks[i];

       }

       for (i = 0; i < N; i++)

       {

              for (j = 0; j < N; j++)

              {

                     f[i][j] = move[j][i];

              }

              ans[i] = (4 - clocks[i]) % 4;

       }

       Guass();

       for (i = 0; i < N; i++)

       {

              x[i] = (x[i] % 4 + 4) % 4;

       }

       for (i = 0; i < N; i++)

       {

              for (j = 1; j <= x[i]; j++)

              {

                     cout << i + 1 << " ";

              }

       }

       cout << endl;

       return 0;

}

原创粉丝点击