Problem A. Crazy Rows
Small input 6 points |
Large input 10 points |
|
Problem
You are given an N x N matrix with 0 and 1 values. You can swap any twoadjacent rows of the matrix.
Your goal is to have all the 1 values in the matrix below or on the main diagonal. That is, for each X where 1 ≤ X ≤ N, there must be no 1 values in row X that are to the right of column X.
Return the minimum number of row swaps you need to achieve the goal.
Input
The first line of input gives the number of cases, T. T test cases follow.
The first line of each test case has one integer, N. Each of the nextN lines contains N characters. Each character is either 0 or 1.
Output
For each test case, output
Case #X: Kwhere X is the test case number, starting from 1, and K is the minimum number of row swaps needed to have all the 1 values in the matrix below or on the main diagonal.
You are guaranteed that there is a solution for each test case.
Limits
1 ≤ T ≤ 60
Small dataset
1 ≤ N ≤ 8
Large dataset
1 ≤ N ≤ 40
Sample
Input | Output |
3 | Case #1: 0 |
题目大意:
输入一个N*N的只有0和1的矩阵,每次可以交换相邻的两行,求把矩阵转化成主对角线上方的元素都是0最小的交换次数。
解题思路:
首先,对于矩阵的每一行我们只关心最右边的1的位置,所以需要先预处理出每一行最右边一行的1的位置。
由于每次只能交换相邻的两行,所以要想步数最少定是用类似于冒泡排序的方法。先通过交换确定最上面一行(先确定最下面一行也可以),再确定第二行,再第三行……
对于每一行的确定,我们只要从这一行往下寻找第一个移动到这里后不会超过对角线的行就可以保证步数最小。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
//#define LOCAL_TEST
const int maxn=40+3;
int N;
char land[maxn][maxn];//矩阵
int a[maxn];//每一行最后一个1出现的位置
int main()
{
#ifndef LOCAL_TEST
freopen("/Users/xuehao/Downloads/A-large-practice.in","r",stdin);
freopen("/Users/xuehao/Documents/s1/s1/out","w",stdout);
#endif
int T;
scanf("%d",&T);
for(int tt=1;tt<=T;++tt)
{
int ans=0;
scanf("%d",&N);
for(int i=0;i<N;++i)
{
scanf("%s",land[i]);
a[i]=-1;//如果没有1,则令最后一个1的位置为-1
for(int j=0;j<N;++j)
if(land[i][j]=='1')
a[i]=j;
}
for(int i=0;i<N;++i)
{
int pos=-1;
for(int j=i;j<N;++j)
if(a[j]<=i)//第一个1不超过位置i的对角线的行
{
pos=j;
break;
}
for(int j=pos;j>i;--j)//交换
{
swap(a[j],a[j-1]);
++ans;
}
}
printf("Case #%d: %d\n",tt,ans);
}
#ifndef LOCAL_TEST
fclose(stdin);
fclose(stdout);
#endif
return 0;
}