zoukankan      html  css  js  c++  java
  • 杂题ZJOI2007 矩阵游戏

    题目描述

    QQ是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏。矩阵游戏在一个N imes NN×N黑白方阵进行(如同国际象棋一般,只是颜色是随意的)。每次可以对该矩阵进行两种操作:

    行交换操作:选择矩阵的任意两行,交换这两行(即交换对应格子的颜色)

    列交换操作:选择矩阵的任意两列,交换这两列(即交换对应格子的颜色)

    游戏的目标,即通过若干次操作,使得方阵的主对角线(左上角到右下角的连线)上的格子均为黑色。

    对于某些关卡,小QQ百思不得其解,以致他开始怀疑这些关卡是不是根本就是无解的!于是小QQ决定写一个程序来判断这些关卡是否有解。

    输入输出格式

    输入格式:

     

    第一行包含一个整数TT,表示数据的组数。

    接下来包含TT组数据,每组数据第一行为一个整数NN,表示方阵的大小;接下来NN行为一个N imes NN×N的0101矩阵(00表示白色,11表示黑色)。

     

    输出格式:

     

    包含TT行。对于每一组数据,如果该关卡有解,输出一行YesYes;否则输出一行NoNo。

     

    输入输出样例

    输入样例#1:
    2
    2
    0 0
    0 1
    3
    0 0 1
    0 1 0
    1 0 0
    
    输出样例#1: 
    No
    Yes
    这道题反正我乍一看根本没看出来是二分图。

    这道题是二分图,先把问题转化一下。怎么样才能让对角线都是1呢?我们知道,显然的同行同列的1是无法分开的。所以这道题就可以转化成,只要每一个行和列都有一个1就可以转化成对角线。所以这道题其实就是看任意行上有没有与之对应的列上有1。把行和列分成两个集合,就是很明显的二分图的板子了。

    代码如下:
     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<queue>
     5 #include<cstring>
     6 using namespace std;
     7 typedef long long ll;
     8 const ll maxn = 1e5 + 7;
     9 ll read()
    10 {
    11     ll a = 0,b = 1;
    12     char c = getchar();
    13     while(c < '0' or c > '9')
    14     {
    15         if(c == '-') b = -1;
    16         c = getchar();
    17     }
    18     while(c >= '0' and c <= '9')
    19     {
    20         a = a * 10 + c - '0';
    21         c = getchar();
    22     }
    23     return a * b;
    24 }
    25 ll t,n,mp[1005][1005],vis[maxn],pri[maxn],ans;
    26 bool find(int x)
    27 {
    28     for(int i=1; i<=n; i++)
    29     {
    30         if(mp[x][i] and vis[i]==0)
    31         {
    32             vis[i] = 1;
    33             if(pri[i] == 0 or find(pri[i]))
    34             {
    35                 pri[i] = x;
    36                 return true;
    37             }
    38         }
    39     }
    40     return false;
    41 }
    42 int main()
    43 {
    44     t = read();
    45     for(int k=1; k<=t; k++)
    46     {
    47         n = read();
    48         memset(mp,0,sizeof(mp));
    49         memset(pri,0,sizeof(pri));
    50         ans = 0;
    51         for(int i=1; i<=n; i++)
    52         {
    53             for(int j=1; j<=n; j++)
    54             {
    55                 mp[i][j] = read();
    56             }
    57         }
    58         for(int i=1; i<=n; i++)
    59         {
    60             memset(vis,0,sizeof(vis));
    61             if(find(i))
    62             ans++;
    63         }
    64         if(ans == n)
    65         printf("Yes
    ");
    66         else
    67         printf("No
    ");
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    【CF1029A】Many Equal Substrings(模拟)
    【CF1028C】Rectangles(线段树)
    【CF1028B】Unnatural Conditions(构造)
    【CF1028A】Find Square(签到)
    【CF1025C】Plasticine zebra(模拟)
    【CF1025A】Doggo Recoloring(签到)
    167.数据传送指令
    166.寻址方式
    165.基础
    164.多媒体操作系统
  • 原文地址:https://www.cnblogs.com/qmcp/p/9579844.html
Copyright © 2011-2022 走看看