zoukankan      html  css  js  c++  java
  • codeforces 441C. Valera and Tubes 解题报告

    题目链接:http://codeforces.com/problemset/problem/441/C

    题目意思:将n * m 的矩阵分成 k 堆。每堆是由一些坐标点(x, y)组成的。每堆里面至少由 >= 2 个坐标点组成,这些坐标点还需要满足: |xi - xi + 1| + |yi - yi + 1| = 1 。这个等式表示遍历堆里面的坐标好像蛇形那样走,也就是坐标点与坐标点之间需要相邻!还有一个条件就是,每个坐标点只能用一次。

          做了一整天= =。改了一个问题,另一个问题又出现了。终于被一个问题攻陷了= =。

          整体思路就是 k - 1堆中,每堆由两个坐标组成,剩下的那一堆,由剩下未用的坐标构成。由于我做的时候是一竖竖地做的(假设 3 * 5的矩阵,1 1 1 2 2 1 2 2...),所以有个问题就是剩下的那堆,从第一行开始走的时候,是从左到右走还是从右到左走?我错误的代码中,判断不了对于分完k-1堆之后,箭头是如何走的!我是通过k-1堆之后被覆盖的总行数的奇偶数来判断的:奇数:从左至右,偶数:从右至左。但是对于行数为奇数来说,就不行了。以下这两种情况足以证实。

          5  9  20

     (被覆盖的总行数为奇数,但正确走法应该是从右至左)

       

          2   2  1

      (与推测相同)

      

         先贴下我错的代码(读者可直接忽略),一场噩梦= =

       (test 24 错了,说堆中有些tube 不符合条件)

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int maxn = 300 + 5;
     8 int vis[maxn][maxn];
     9 
    10 int main()
    11 {
    12     int n, m, k;
    13     while (scanf("%d%d%d", &n, &m, &k) != EOF)
    14     {
    15         memset(vis, 0, sizeof(vis));
    16         int row = 1, y = 1;
    17         int cnt, tmp, f = 0, sum = 0;
    18         for (cnt = 1; cnt <= k-1; )
    19         {
    20             if (y+1 > m)
    21                 break;
    22             printf("2 %d %d %d %d
    ", row, y, row, y+1);
    23             vis[row][y] = vis[row][y+1] = 1;
    24             sum += 2;
    25             row++;
    26             cnt++;
    27             if (!(row % n) && cnt+1 <= k-1)
    28             {
    29                 printf("2 %d %d %d %d
    ", row, y, row, y+1);
    30                 vis[row][y] = vis[row][y+1] = 1;
    31                 sum += 2;
    32                 y += 2;
    33                 row = 1;
    34                 f = 1;
    35                 cnt++;
    36             }
    37         }
    38         int col = m;
    39         for (int row = 1; row+1 <= n && cnt <= k-1; row += 2, cnt++)
    40         {
    41             printf("2 %d %d %d %d
    ", row, col, row+1, col);
    42             vis[row][col] = vis[row+1][col] = 1;
    43             sum += 2;
    44         }
    45         tmp = (!f ? row-1 : n);
    46       //  printf("tmp = %d
    ", tmp);
    47         if ((n*m)-sum)
    48         {
    49             printf("%d ", n*m-sum);
    50             int start = (tmp&1 ? 1 : 0);  // 奇数顺着来走
    51             for (int row = 1; row <= n; row++)
    52             {
    53                 if (start)
    54                 {
    55                     for (int col = 1; col <= m; col++)
    56                     {
    57                         if (!vis[row][col])
    58                             printf("%d %d ", row, col);
    59                     }
    60                 }
    61                 else
    62                 {
    63                     for (int col = m; col >= 1; col--)
    64                     {
    65                         if (!vis[row][col])
    66                             printf("%d %d ", row, col);
    67                     }
    68                 }
    69                 start ^= 1;
    70             }
    71         }
    72         printf("
    ");
    73     }
    74     return 0;
    75 }

         AC代码(真是简单就为美啊~~~)

         规规矩矩,一行行顺着来做

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 int n, m, k;
     8 
     9 void next(int &x, int &y)
    10 {
    11     if (y == 1)
    12     {
    13         if (x & 1)
    14             y++;
    15         else
    16             x++;
    17     }
    18     else if (y == m)
    19     {
    20         if (x & 1)
    21             x++;
    22         else
    23             y--;
    24     }
    25     else if (x & 1)
    26         y++;
    27     else
    28         y--;
    29 }
    30 
    31 int main()
    32 {
    33     while (scanf("%d%d%d", &n, &m, &k) != EOF)
    34     {
    35         int x = 1, y = 1;
    36         int cnt = k;
    37         while (cnt > 1)
    38         {
    39             printf("2");
    40             printf(" %d %d", x, y);
    41             next(x, y);
    42             printf(" %d %d
    ", x, y);
    43             next(x, y);
    44             cnt--;
    45         }
    46         printf("%d", n*m-2*(k-1));
    47         while (x >= 1 && x <= n && y >= 1 && y <= m)
    48         {
    49             printf(" %d %d", x, y);
    50             next(x, y);
    51         }
    52         puts("");
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    spring in action小结4.1
    spring in action小结3 运行时值注入
    python-__init__.py 与模块对象的关系
    Python-常用库扩展
    Qt-优化布局结构
    Python-文件修改器
    C语言-数据结构(一)
    Python-PyQt4学习笔记
    Python-PyQt4学习资料汇总
    Linux-查看C语言手册及man的特殊用法
  • 原文地址:https://www.cnblogs.com/windysai/p/3821012.html
Copyright © 2011-2022 走看看