题目大意
解题思路
- 贪心策略:
- (1) 先确定应该把那一行移动到第一行,选择的策略是将能够移动到第一行中最近的那一行移动到第一行。
- (2) 然后按相同策略确定第二行、第三行…
- 正确性证明:
- 使用贪心交换准则,将最近的那一行移动到当前确定的行,至少不会比将其他行移动到当前确定的步数多。
- 技巧:
-
每行只用一个数记录当前最后一个1的位置。比如矩阵
111
110
100就可以表示为2,1,0
-
当前确定的第
i
行,对现有矩阵的第 k k k行,若其满足 k > = i 且 a [ k ] < = i k>=i 且 a[k] <= i k>=i且a[k]<=i ,则其是可行的,则从第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;
}