zoukankan      html  css  js  c++  java
  • HDU 5386 Cover

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5386

    题目大意:给一个初始矩阵(n×n)、一个目标矩阵(n×n)和m个操作,要求找到一种操作顺序,使初始矩阵变成目标矩阵。操作共有两种,如下:

      L x y: 把当前矩阵第x列的数全变为y
      H x y: 把当前矩阵第x行的数全变为y

    输入格式:先输入case数T,每个case第一行是两个整数n和m,接下来n行输入初始矩阵,再下来n行输入目标矩阵。最后m行输入操作。
      1color[i][j]n,color[i][j]为数组元素。
      T=5
      1n100
      1m500

    分析:根据数据范围推解题方法,此题对数组元素的大小做了限制,可以从这点下手。

      统计目标矩阵中每个数出现的次数,对列亦是。若有个操作是L x y,而目标矩阵第x列的值全是y,那显然,这个操作最后一次做是合情合理的,去掉这一列后,又是一个新问题,可以找到新的可以“最后一步”做的操作。依次类推,每次找一个合法的操作,逆序输出即可。

    参考代码:

    主体代码是队友写的,写的够简洁的~

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    struct node{
        int t,x,y;
    }b[510];
    int c[2][110][110],a[110][110],mark[510],ans[510],ans2[510];
    char s[10];
    bool vis[2][110];
    int main(){
        int t,n,m;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    scanf("%d",&a[i][j]);
            memset(c,0,sizeof(c));
            memset(mark,0,sizeof(mark));
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    scanf("%d",&a[i][j]);
                    c[0][j][a[i][j]]++;
                    c[1][i][a[i][j]]++;
                }
            int cnt=0,d[2];
            d[0]=n;
            d[1]=n;
            for(int i=0;i<m;i++){
                scanf("%s%d%d",&s,&b[i].x,&b[i].y);
                if(s[0]=='L') b[i].t=0;
                    else b[i].t=1;
            }
            memset(vis, 0, sizeof(vis));
            for(int j=0;j<m;j++)
                for(int i=0;i<m;i++)
                if(!mark[i]){
                    if(d[b[i].t]==c[b[i].t][b[i].x][b[i].y])
                    {
                        if(vis[b[i].t][b[i].x]) continue;
                        vis[b[i].t][b[i].x] = 1;
                        mark[i]=1;
                        ans[m-cnt-1]=i+1;
                        cnt++;
                        d[b[i].t^1]--;
                        for(int k=1;k<=n;k++){
                            if(vis[b[i].t^1][k]) continue;
                            if(b[i].t) c[b[i].t^1][k][a[b[i].x][k]]--;
                            else c[b[i].t^1][k][a[k][b[i].x]]--;
                        }
                    }
                }
            int flag=0;
            for(int i=0;i<m;i++)
                if(!mark[i]){
                    ans[m-cnt-1]=i+1;
                    cnt++;
                }
            for(int i=0;i<m;i++){
                if(flag==1) printf(" ");
                flag=1;
                printf("%d",ans[i]);
            }
            puts("");
        }
    }
  • 相关阅读:
    C++细节3
    C++细节2
    C++细节1
    连通域标记方法
    dll动态链接库入门2
    UnixShell编程(第三版)
    Xcode 快捷键
    mysql在linux上的一点操作
    mysql 语句
    开机自动启动
  • 原文地址:https://www.cnblogs.com/beisong/p/4728277.html
Copyright © 2011-2022 走看看