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 }
  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/windysai/p/3821012.html
Copyright © 2011-2022 走看看