• L


    Time Limit : 1 Second      Memory Limit : 65536 KB

    Source : 第十届山东省ACM省赛

    Problem Link : ZOJ 4124

    Author : Houge  Date : 2019-5-19

    题目大意:

      给你n个数(不知道谁大谁小)和m个关系(ai,bi),每个关系代表ai严格大于bi。问你能否通过已知推出可能的中间项k的位置。(题目保证n一定是奇数)

    分析:

      比赛时想用拓扑排序,结果因为菜没写出来,赛后听了学长用floyd的思路,感觉还不错便敲了一发。(不了解floyd的可先百度学习一下,不难)

      ·我们定义两个二维数组matrix[i][j]和num[2][n],其中matrix[i][j]=1时代表第i个数严格大于第j个数,num[0][n]代表比n小的数的个数,num[1][n]代表比n大的数的个数。

      ·跑一遍floyd,对于每一个通路,都可以认为它的起点严格大于终点,即给matrix[start][end]赋值为1。

      ·考虑一下不可能存在的情况(如样例2的第一个数严格大于自身),即图中出现自环。

      ·再对matrix进行遍历,更新num数组。

      ·最后按要求输出即可。

    代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int n,m,matrix[105][105],num[2][105],flag=0;
     6 
     7 void floyd()
     8 {
     9     int i,j,k;
    10 
    11     for(k=1;k<=n;k++)      //floyd
    12         for(i=1;i<=n;i++)
    13             for(j=1;j<=n;j++)
    14                 if(matrix[i][k]&&matrix[k][j])
    15                     matrix[i][j]=1;
    16 
    17     for(i=1;i<=n;i++)      //判断是否有自环
    18         for(j=1;j<=n;j++)
    19             if(matrix[i][j]&&matrix[j][i])
    20             {
    21                 flag=1;
    22                 return;
    23             }
    24 
    25     for(i=1;i<=n;i++)    //维护更新num数组
    26         for(j=1;j<=n;j++)
    27             if(matrix[i][j])
    28             {
    29                 num[0][i]++;
    30                 num[1][j]++;
    31             }
    32 }
    33 
    34 int main()
    35 {
    36     int t;
    37     scanf("%d",&t);
    38     while(t--)
    39     {
    40         int i,a,b;
    41 
    42         memset(matrix,0,sizeof(matrix));    //初始化
    43         memset(num,0,sizeof(num));
    44         flag=0;
    45 
    46         scanf("%d%d",&n,&m);
    47         for(i=0;i<m;i++)    //预处理
    48         {
    49             scanf("%d%d",&a,&b);
    50             matrix[a][b]=1;
    51         }
    52         floyd();
    53         if(flag==0)    //输出,当一个数比它大的和比它小的数的个数都小于等于n/2时,可视该项为中间项
    54         {
    55             for(i=1;i<=n;i++)
    56             {
    57                 if(num[0][i]<=n/2&&num[1][i]<=n/2) printf("1");
    58                 else printf("0");
    59             }
    60             printf("
    ");
    61         }
    62         else
    63         {
    64             for(i=0;i<n;i++) printf("0");
    65             printf("
    ");
    66         }
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    文件I/O(不带缓冲)之write函数
    文件I/O(不带缓冲)之read函数
    webpack4.x版本splitChunksPlugin的配置项详解与实际应用场景
    关于使用express作为spa应用服务的问题
    url 的正则表达式:path-to-regexp
    node.js、js读取excel、操作excel、创建excel之js-xlsx.js
    Web前端之iframe详解
    html中的meta标签是什么?有哪些属性?
    大型互联网架构概述,看完文章又涨知识了
    redis 的过期策略都有哪些?内存淘汰机制都有哪些?
  • 原文地址:https://www.cnblogs.com/CSGOBESTGAMEEVER/p/10890595.html
Copyright © 2020-2023  润新知