1105. Spiral Matrix (25) / 1050. 螺旋矩阵(25) 考察代码优化,而非算法

来源:互联网 发布:药品网络市场监管 编辑:程序博客网 时间:2024/06/03 17:55

1105. Spiral Matrix (25)

时间限制
150 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasing order. A spiral matrix is filled in from the first element at the upper-left corner, then move in a clockwise spiral. The matrix has m rows and ncolumns, where m and n satisfy the following: m*n must be equal to N; m>=n; and m-n is the minimum of all the possible values.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N. Then the next line contains N positive integers to be filled into the spiral matrix. All the numbers are no more than 104. The numbers in a line are separated by spaces.

Output Specification:

For each test case, output the resulting matrix in m lines, each contains n numbers. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.

Sample Input:
1237 76 20 98 76 42 53 95 60 81 58 93
Sample Output:
98 95 9342 37 8153 20 7658 60 76

提交代码

http://www.patest.cn/contests/pat-a-practise/1105

思路和问题:

这题应该算是模拟题 ,就是按照螺旋方式一步步的赋值,不过原先忘了 在每一圈的每一步都加上break判断语句 导致有错误,圈数显然应该是小于行数m的


ac代码:

#include <cstdio>#include <cstdlib>#include <vector>#include <algorithm>using namespace std ;bool cmp(int a, int b){return a > b ;}int main(){//freopen("in.txt" , "r" , stdin) ;int nn , i , j ;vector<int> v ;scanf("%d" , &nn) ;v.resize(nn+1) ;for(i = 0 ; i < nn ; i++){scanf("%d" , &v[i]) ;}if(nn == 0){          printf("0\n");          return 0;      } sort(v.begin() , v.end(), cmp) ;int m, n;      int minDiff = 9999999;      for(i=1; i<=nn; i++){          for(j=i; j<=nn; j++){              if(i*j>nn){                  break;              }              if(i*j==nn && (j-i)<minDiff){                  m=j;                   n=i;                  minDiff=(j-i);              }          }      } if(n == 1 || m == nn){for(i = 0 ; i < nn ; i++){printf("%d\n" , v[i]) ;}return 0 ;}int index = 0 , k;vector<vector<int>> b;      b.resize(m+1, vector<int>(n+1,0)); // 一圈一圈的赋值 , break都需要for(k = 0 ; k < m ; k++){// 从左到右for(i = k ; i <= n - k - 1 ; i ++){b[k][i] = v[index++] ;if(index >= nn)break;}if(index >= nn)break;// 从上到下for(i = k+1 ; i <= m - k - 1 ; i ++){b[i][n-k-1] = v[index++] ;if(index >= nn)break;}if(index >= nn)break;// 从右到左for(i = n-k-2 ; i >= k; i --){b[m-k-1][i] = v[index++] ;if(index >= nn)break;}if(index >= nn)break;//从下到上for(i = m-k-2 ; i >= k + 1; i --){b[i][k] = v[index++] ;if(index >= nn)break;}if(index >= nn)break ;}for(i = 0 ;i < m ; i++){printf("%d" , b[i][0]) ;for(j = 1 ; j < n ; j ++){printf(" %d" , b[i][j]) ;}printf("\n") ;}return 0 ;}

上面的代码太乱了,这题不涉及到什么算法,主要是螺旋举证处理的代码如何优化,写的精练

下面的ac代码是改进版 

#include <cstdio>  #include <cstdlib>  #include <vector>  #include <algorithm>  using namespace std;bool cmp(int a, int b){return a > b;}int f(int stai, int staj, int endi, int endj, vector<vector<int>> &rs, vector<int> v, int index){int tmpIndex = index;//保存index// 往右 for (int j = staj; j <= endj; j++)rs[stai][j] = v[index++];//下 for (int i = stai+1; i <= endi; i++)rs[i][endj] = v[index++];if (staj != endj && stai != endi) //  有多行 多列时 才有必要向左 再向上(因为这里可能会出现访问数组出界){//左 for (int j = endj - 1; j >= staj; j--)rs[endi][j] = v[index++];//上for (int i = endi - 1; i > stai; i--)rs[i][staj] = v[index++];}return index - tmpIndex; // 返回当前处理了多少个数据}int main(){//freopen("in.txt" , "r" , stdin) ;  int nn, i, j;vector<int> v;scanf("%d", &nn); // 长度v.resize(nn);for (i = 0; i < nn; i++){scanf("%d", &v[i]);}if (nn == 0){printf("0\n");return 0;}sort(v.begin(), v.end(), cmp); //从大到小排序// 求解 m,n int m, n;int minDiff = 9999999;for (i = 1; i <= nn; i++){for (j = i; j <= nn; j++){if (i*j>nn){break;}if (i*j == nn && (j - i)<minDiff){m = j;n = i;minDiff = (j - i);}}}// 只有1列的情况 直接就可以输出了if (n == 1 || m == nn){for (i = 0; i < nn; i++)printf("%d\n", v[i]);return 0;}// 一般情况 m 行 n 列 构造矩阵vector< vector<int> > rs;rs.resize(m, vector<int>(n, 0));// 螺旋赋值int stai = 0, staj = 0;int endi = m - 1, endj = n - 1;int index = 0; // 每次赋值时 从v的index下标开始while (index < nn){int cnt = f(stai, staj, endi, endj, rs, v, index);// 处理一圈的函数 , 单独封装index += cnt;if (index >= nn)break;stai++;staj++;endi--;endj--;}//打印结果for (i = 0; i < m; i++){printf("%d", rs[i][0]);for (j = 1; j < n; j++)printf(" %d", rs[i][j]);printf("\n");}return 0;}

ac代码2

#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <iostream>#include <cstring>#include <string>#include <vector>#include <stack>#include <queue>#include <map>#include <set>#include <algorithm>#include <sstream>using namespace std;const int N = 10005;int num;int v[N];int mm,nn;vector<vector<int>> ans;int show(int stai,int staj,int endi,int endj,int index){  // 竖线  if(staj == endj)  {    for(int i= stai ; i <= endi;i++)      ans[i][staj] = v[index++];    return index;  }  //横线  if(stai == endi)  {    for(int j = staj ; j <= endj; j++)      ans[stai][j] = v[index++];    return index;  }  //  for(int j= staj ;j <= endj;j++)  {    ans[stai][j] = v[index++];  }  //  for(int i = stai + 1; i <= endi;i++)  {    ans[i][endj] = v[index++];  }  //  for(int j = endj - 1; j >= stai ; j--)  {    ans[endi][j] = v[index++];  }  //  for(int i = endi - 1; i > stai ; i--)  {    ans[i][staj] = v[index++];  }  return index;}bool isPrime(int n){  if(n == 1)    return false;  if(n == 2)    return true;  for(int i=2;i*i <= n;i++)  {    if(n % i == 0)      return false;  }  return true;}int main(){  //freopen("in.txt","r",stdin);   int i,j;  while(scanf("%d",&num) != EOF)  {    for(i=0;i<num;i++)    {      scanf("%d",&v[i]);    }      sort(v+0,v+num,[](int a, int b){return a>b;});        if(num == 1 || isPrime(num))    {      for(i= 0;i < num;i++)        printf("%d\n",v[i]);      continue;    }    // 求m*n    int minVal = 0x7fffffff;    for(int n = 1;n*n <= num;n++)    {      for(int m = n;m <=num;m++)      {        if(m*n == num)        {          if(m - n < minVal)          {            mm = m;            nn = n;          }        }      }    }    ans.resize(mm,vector<int>(nn));    i = 0;    int index = 0;    while(index < num)    {      index = show(i,i,mm - 1 - i, nn -1 - i,index);      i++;    }    for(i=0;i<mm;i++)    {      printf("%d",ans[i][0]);      for(j= 1;j<nn;j++)      {        printf(" %d",ans[i][j]);      }      printf("\n");    }  }// end while  return 0;}

0 0