Crazy Rows————GCJ 2009 Round2A(简单贪心)

来源:互联网 发布:linux查看内存插槽 编辑:程序博客网 时间:2024/06/07 13:38

题目:给定一个由0和1组成的矩阵,只允许交换相邻的两行。要把矩阵化为下三角矩阵,即主对角线上方的元素都为0,问至少需要交换几次。(1<=N<=40)

input:3

           001

           100

           010

output:2(1和2先交换,再交换2和3)


思路:先考虑最后形成的下三角矩阵的情形,肯定是第一行第一个数后面的都是0,第二行第二个数后面的都是0,依次类推。

          那么哪几行可以被交换到第一行?

          只要考虑每行最后一个1出现的位置。并找到离第一行最近的一个。交换过来。接下来的以此类推。

         为什么可行?在纸上模拟一下就知道,能交换到第一行的肯定能放到第二行,第三行,反之则不一定。如果有两行同时满足第一行和第二行的要求,先把最靠近的换到第一行,这样至少不会比另一种策略用的步数多。


代码

#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <cmath>#include <queue>#include <string>#include <map>#include <iostream>using namespace std;#define INF 1e9+7#define MAXN 100010int n;char a[50];int b[50];bool used[50];int main(){    int n;    scanf("%d",&n);    getchar();    for(int i=0;i<n;i++)    {        b[i]=-1;        used[i]=false;        scanf("%s",a);        for(int j=n-1;j>=0;j--)        {            if(a[j]=='1')            {                b[i]=j;                break;            }        }    }    int s=0;    for(int i=0;i<n;i++)    {        int ans=-1;        for(int j=i;j<n;j++)        {            if(b[j]<=i){                ans=j;                break;            }        }        for(int j=ans;j>i;j--)        {            swap(b[j],b[j-1]);            s++;        }    }    printf("%d\n",s);}


          

0 0