码迷,mamicode.com
首页 > 其他好文 > 详细

L - Median(ZOJ 4124)

时间:2019-05-19 20:36:34      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:第一个   printf   c++   \n   山东   比赛   amp   ble   emc   

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("\n");
61         }
62         else
63         {
64             for(i=0;i<n;i++) printf("0");
65             printf("\n");
66         }
67     }
68     return 0;
69 }

 

L - Median(ZOJ 4124)

标签:第一个   printf   c++   \n   山东   比赛   amp   ble   emc   

原文地址:https://www.cnblogs.com/CSGOBESTGAMEEVER/p/10890595.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!