2016暑期集训1-D
CodeForces 266C Below the Diagonal
想法题,矩阵换行换列
传送门:HustOJ
传送门:CodeForce
题意
给你一个n阶01矩阵,保证里面有n-1个1,其余0。你每次可以交换其中两行或两列,不要求交换次数最小,但不能大于10000。最后使得矩阵的1全在主对角线下方。
思路
- 从n阶开始看,每次先使第n列全0,再使第n行有1,然后递归处理n-1阶矩阵,直到n=1。
- 对矩阵加边,记录每行每列的1的个数,递归之前处理边,如果第n行某位置有1,那么把该列的1个数减1。
- 记录交换方法,最后输出。
代码
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int MAXN = 1007;
const int oo = 2000000007;
const long long int loo = 2000000000000000007ll;
typedef pair<int , pair<int , int > > P;
queue <P> que;
int q [ MAXN ] [ MAXN ];
void solve ( int n )
{
if ( n == 1 ) return;
else
{
if ( q [ 0 ] [ n ] == 0 )//最后一列全是0
{
if ( q [ n ] [ 0 ] != 0 )//最后一行有1
{
for ( int i = 1; i <= n; i++ )
{
if ( q [ n ] [ i ] == 1 )
{
q [ 0 ] [ i ]--;
}
}
solve ( n - 1 );
}
else//最后一行没有1
{
for ( int i = 1; i <= n; i++ )
{
if ( q [ i ] [ 0 ] != 0 )
{
swap ( q [ i ] , q [ n ] );
que.push ( P ( 1 , make_pair ( i , n ) ) );
break;
}
}
for ( int i = 1; i <= n; i++ )
{
if ( q [ n ] [ i ] == 1 )
{
q [ 0 ] [ i ]--;
}
}
solve ( n - 1 );
}
}
else//最后一列有1
{
for ( int i = 1; i <= n; i++ )
{
if ( q [ 0 ] [ i ] == 0 )
{
for ( int j = 0; j <= n; j++ )
{
swap ( q [ j ] [ i ] , q [ j ] [ n ] );
}
que.push ( P ( 2 , make_pair ( i , n ) ) );
break;
}
}
if ( q [ n ] [ 0 ] != 0 )//最后一行有1
{
for ( int i = 1; i <= n; i++ )
{
if ( q [ n ] [ i ] == 1 )
{
q [ 0 ] [ i ]--;
}
}
solve ( n - 1 );
}
else//最后一行没有1
{
for ( int i = 1; i <= n; i++ )
{
if ( q [ i ] [ 0 ] != 0 )
{
swap ( q [ i ] , q [ n ] );
que.push ( P ( 1 , make_pair ( i , n ) ) );
break;
}
}
for ( int i = 1; i <= n; i++ )
{
if ( q [ n ] [ i ] == 1 )
{
q [ 0 ] [ i ]--;
}
}
solve ( n - 1 );
}
}
}
}
int main ( )
{
while ( que.size ( ) != 0 )
{
que.pop ( );
}
memset ( q , 0 , sizeof ( q ) );
int n;
scanf ( "%d" , &n );
int a , b;
while ( scanf ( "%d%d" , &a , &b ) == 2 )
{
q [ a ] [ b ] = 1;
q [ 0 ] [ b ]++;
q [ a ] [ 0 ]++;
}
solve ( n );
printf ( "%d\n" , que.size ( ) );
while ( que.size ( ) != 0 )
{
P p = que.front ( );
que.pop ( );
printf ( "%d %d %d\n" , p.first , p.second.first , p.second.second );
}
system ( "pause" );
return 0;
}