hdu5386(2015多校8)--Cover

题目链接:点击打开链接

题目大意:给出一个n*n的矩阵的初始值,和最终的值,现在有m个操作 L i j ,将第i列的值重置为j,H i j,将第i行的值重置为j。问m个操作应该怎么执行,可以完成矩阵的变化。

从最终的值向前找寻方案,每次找行和列中剩余的颜色全部相同的,看是否存在没被使用的操作可以完成它,如果有就记录下来,那么最终按照记录的逆序输出,就是可以完成变化的序列啦

#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std ;
struct node{
    char s[5] ;
    int x , y ;
}p[510] ;
int Map[110][110] ;
int vis[510] , n , m ;
stack <int> sta ;
void solve(int k) {
    int i ;
    if( p[k].s[0] == 'L' ) {
        for(i = 1 ; i <= n ; i++) {
            if( Map[i][ p[k].x ] == 0 ) continue ;
            if( Map[i][ p[k].x ] != p[k].y ) break ;
        }
        if( i > n ) {
            sta.push(k) ;
            vis[k] = 1 ;
            for(i = 1 ; i <= n ; i++)
                Map[i][ p[k].x ] = 0 ;
        }
    }
    else {
        for(i = 1 ; i <= n ; i++) {
            if( Map[ p[k].x ][i] == 0 ) continue ;
            if( Map[ p[k].x ][i] != p[k].y ) break ;
        }
        if( i > n ) {
            sta.push(k) ;
            vis[k] = 1 ;
            for(i = 1 ; i <= n ; i++)
                Map[ p[k].x ][i] = 0 ;
        }
    }
}
int main() {
    int t , i , j  ;
    scanf("%d", &t) ;
    while( t-- ) {
        scanf("%d %d", &n, &m) ;
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ;j++)
                scanf("%d", &Map[i][j]) ;
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ;j++)
                scanf("%d", &Map[i][j]) ;
        for(i = 0 ; i < m ; i++)
            scanf("%s %d %d", p[i].s, &p[i].x, &p[i].y) ;
        memset(vis,0,sizeof(vis)) ;
        while( !sta.empty() ) sta.pop() ;
        for(i = 0 ; i < m ; i++) {
            for(j = 0 ; j < m ; j++) {
                if( vis[j] ) continue ;
                solve(j) ;
            }
        }
        for(i = 1 ; i < m ; i++) {
            printf("%d ", sta.top()+1 ) ;
            sta.pop() ;
        }
        printf("%d\n", sta.top()+1 ) ;
        sta.pop() ;
    }
    return 0 ;
}


你可能感兴趣的:(hdu5386(2015多校8)--Cover)