膜拜诸位100ms内的大牛,实在想不出什么好的算法了。

代码:
#include <stdio.h>

int main()
{
  int w[86];
  int u[86][4];
  int p[24][4] = {
    {0, 1, 2, 3},
    {0, 1, 3, 2},
    {0, 2, 1, 3},
    {0, 2, 3, 1},
    {0, 3, 1, 2},
    {0, 3, 2, 1},
    {1, 0, 2, 3},
    {1, 0, 3, 2},
    {1, 2, 0, 3},
    {1, 2, 3, 0},
    {1, 3, 0, 2},
    {1, 3, 2, 0},
    {2, 0, 1, 3},
    {2, 0, 3, 1},
    {2, 1, 0, 3},
    {2, 1, 3, 0},
    {2, 3, 0, 1},
    {2, 3, 1, 0},
    {3, 0, 1, 2},
    {3, 0, 2, 1},
    {3, 1, 0, 2},
    {3, 1, 2, 0},
    {3, 2, 0, 1},
    {3, 2, 1, 0}
  };
  int qp[4][4];
  int i, j, k;
  int i1, j1, k1;
  int m, n, x, z, s, r;

  z = 0;
  for(i=0; i<65536; ++i)
  {
    m = 0;
    n = 0;
    for(j=0; j<16; ++j) if ((i>>j)&1) { ++n; m += j; }
    if ((n==4)&&(m==30))
    {
      for(k=j=0; j<16; ++j) if ((i>>j)&1) u[z][k++] = j;
      w[z++] = i;
    }
  }
  s = 0;
  for(i=0; i<z; ++i)
  {
    for(j=0; j<z; ++j)
    {
      if (w[i]&w[j]) continue;
      m = w[i]|w[j];
      for(k=0; k<z; ++k)
      {
        if (m&w[k]) continue;
        n = (m|w[k])^0xFFFF;
        for(i1=0; i1<24; ++i1)
        {
          qp[0][0] = u[i][p[i1][0]];
          qp[0][1] = u[i][p[i1][1]];
          qp[0][2] = u[i][p[i1][2]];
          qp[0][3] = u[i][p[i1][3]];
          for(j1=0; j1<24; ++j1)
          {
            qp[1][0] = u[j][p[j1][0]];
            qp[1][1] = u[j][p[j1][1]];
            qp[1][2] = u[j][p[j1][2]];
            qp[1][3] = u[j][p[j1][3]];
            for(k1=0; k1<24; ++k1)
            {
              qp[2][0] = u[k][p[k1][0]];
              qp[2][1] = u[k][p[k1][1]];
              qp[2][2] = u[k][p[k1][2]];
              qp[2][3] = u[k][p[k1][3]];
              x = 30-qp[0][3]-qp[1][2]-qp[2][1];
              r = 30-qp[0][0]-qp[1][0]-qp[2][0];
              if (x != r) continue;
              qp[3][0] = r;
              x = 30-qp[0][0]-qp[1][1]-qp[2][2];
              r = 30-qp[0][3]-qp[1][3]-qp[2][3];
              if (x != r) continue;
              qp[3][3] = r;
              qp[3][1] = 30-qp[0][1]-qp[1][1]-qp[2][1];
              qp[3][2] = 30-qp[0][2]-qp[1][2]-qp[2][2];
              if ((qp[3][0]<0)|(qp[3][1]<0)|(qp[3][2]<0)|(qp[3][3]<0)) continue;
              x = (1<<qp[3][0])|(1<<qp[3][1])|(1<<qp[3][2])|(1<<qp[3][3]);
              if (x^n) continue;
              ++s;
              printf("Case %d\n", s);
              for(x=0; x<4; ++x)
              {
                printf("%2d %2d %2d %2d\n", qp[x][0]+1, qp[x][1]+1, qp[x][2]+1, qp[x][3]+1);
              }
              printf("\n");
            }
          }
        }
      }
    }
  }
  return 0;
}