• codeforces B. Multitasking 解题报告


    题目链接:http://codeforces.com/problemset/problem/384/B

    题目意思:给出n个数组,每个数组包括m个数字,当k = 0 时,需要把n个数组都按照从小到大的顺序排列,k = 1则把n个数组里面的数字按照从大到小的顺序排列。

       直接模拟即可,不过有个地方注意下是可以减少工作量的,当处理第 i 行的时候,不再需要移动前 i - 1 行的数组下标。因为前 i - 1行的数组都排好序了。

    TimeMemory
    46 ms 500 KB

        

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 1000 + 10;
     8 const int maxm = 100 + 5;
     9 
    10 int a[maxn][maxm];
    11 int ans[5000][2];
    12 
    13 int main()
    14 {
    15     int i, j, l, n, m, k, tj, cnt;
    16     while (scanf("%d%d%d", &n, &m, &k) != EOF)
    17     {
    18         for (i = 1; i <= n; i++)
    19         {
    20             for (j = 1; j <= m; j++)
    21                 scanf("%d", &a[i][j]);
    22         }
    23         cnt = 0;
    24         for (i = 1; i <= n; i++)  // n 行
    25         {
    26             for (j = 1; j < m; j++)  // m 列
    27             {
    28                 tj = j;
    29                 int tmp = a[i][j];
    30                 for (l = j+1; l <= m; l++)   
    31                 {
    32                     if (tmp > a[i][l] && k == 0 || tmp < a[i][l] && k == 1)
    33                     {
    34                         tmp = a[i][l];    // 找出第 i 行中第 j 个最少的数
    35                         tj = l;
    36                     }
    37                 }
    38                 if (j != tj)
    39                 {
    40                     swap(a[i][tj], a[i][j]);   // 找完之后要交换
    41                     if (k == 0)
    42                     {
    43                         ans[cnt][0] = j;
    44                         ans[cnt][1] = tj;
    45                     }
    46                     else
    47                     {
    48                         ans[cnt][0] = tj;
    49                         ans[cnt][1] = j;
    50                     }
    51                     cnt++;
    52                     for (l = i+1; l <= n; l++)   // 处理第i+1 ~ n 行的数组
    53                     {
    54                         if (a[l][j] > a[l][tj] && k == 0 || a[l][j] < a[l][tj] && k == 1)
    55                             swap(a[l][j], a[l][tj]);
    56                     }
    57                 }
    58             }       
    59         }
    60         printf("%d
    ", cnt);
    61         for (i = 0; i < cnt; i++)
    62             printf("%d %d
    ", ans[i][0], ans[i][1]); 
    63     }
    64     return 0;
    65 }

     解法二:堪称暴力中的暴力!!内存都省了

    TimeMemory
    78 ms 0 KB

          

            k = 0:从小到大排列。意味着所有数组中的第一个数是最小的!这个最小的数如何找?无非就在该行中的某一个数里面。由于不确定在哪里,但用两重循环势必能找出,于是就有了以下简单的方法:对于i = 1,a[i] 可能不是最小的数,于是不断地跟a[i+1], a[i+2], ..., a[m] 比较,即找出排在第一个的数输出 1, 2;  1, 3;  ...; 1, m 即可,这样能能保证每个数组都能找出最小的数。第二个最小的数就是2, 3;  2,  4; ...;  2, m了,后面的依次类推。但主要题目中说的,当第 i  个位置的 value  > 第 j 个位置的 value 才能交换这个条件。k = 1 则是2, 1; 3, 1; ...; m 1 输出 。

          

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main()
     5 {
     6     int n, m, k, i, j;
     7     while (cin >> n >> m >> k)
     8     {
     9         for (i = 0; i < n * m; i++)
    10             cin >> j;
    11         cout << m * (m - 1) / 2 << endl;
    12         for (i = 1; i < m; i++)
    13         {
    14             for (j = i+1; j <= m; j++)
    15             {
    16                 if (!k)
    17                     cout << i << " " << j << endl;
    18                 else
    19                     cout << j << " " << i << endl;
    20             }
    21         }
    22     }
    23     return 0;
    24 } 
  • 相关阅读:
    POJ3164 Command Network
    UVa11401 Triangle Counting
    UVa11174 Stand in a Line
    UVa11806 Cheerleaders
    Uva11538 Chess Queen
    Bzoj3130 [Sdoi2013]费用流
    Bzoj3262 陌上花开
    模拟25A 题解
    模拟24 题解
    模拟23 题解
  • 原文地址:https://www.cnblogs.com/windysai/p/3543197.html
Copyright © 2020-2023  润新知