题目:给定一个由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 100010
int 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);
}