挑战程序设计竞赛: Crazy Rows

题目大意

在这里插入图片描述
在这里插入图片描述

解题思路

  • 贪心策略:
    • (1) 先确定应该把那一行移动到第一行,选择的策略是将能够移动到第一行中最近的那一行移动到第一行。
    • (2) 然后按相同策略确定第二行、第三行…
  • 正确性证明:
    • 使用贪心交换准则,将最近的那一行移动到当前确定的行,至少不会比将其他行移动到当前确定的步数多。
  • 技巧:
    • 每行只用一个数记录当前最后一个1的位置。比如矩阵

      111
      110
      100

      就可以表示为2,1,0

    • 当前确定的第i行,对现有矩阵的第 k k 行,若其满足 k > = i a [ k ] < = i k>=i 且 a[k] <= i ,则其是可行的,则从第i个位置从左向右扫描,扫到第一个满足的行,就模拟交换将其放在第 i i 行,并记录交换次数。

代码

#include<iostream>
using namespace std;
const int MAXN = 40+2;

int a[MAXN];
int main()
{
    int N;
    string line;
    while(cin >> N)
    {
        for(int i=0; i<N; i++)
        {
            cin >> line;
            a[i] = 0;
            for(int j=line.length()-1; j>=0; j--)
            {
                if(line[j] == '1')
                {
                    a[i] = j;
                    break;
                }
            }
        }

        int ans = 0;
        for(int i=0; i<N; i++)
        {
            for(int j=i; j<N; j++)
            {
                if(a[j] <= i)
                {
                    for(int k=j-1; k>=i; k--)
                    {
                        swap(a[k], a[k+1]);
                        ans++;
                    }
                    break;
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Wangpeiyi9979/article/details/93758110