Gossiping --解题报告

      下面是近期解决的ACM题目,差不多有一个月没连续上poj了。偶间有网友叫我帮他做ACM题目,于是又踏上ACM的征途。顺带把这题目提交到我的主战场poj的ACM.

 

 

题的出处:

(吉林ACM):http://acm.jlu.edu.cn/joj/showproblem.php?pid=1302

(北大ACM):http://acm.pku.edu.cn/JudgeOnline/problem?id=1370   

 

 

 

题目大意:

三个主要变量,n,d,s。n是线路的条数,d是司机的人数。s是站点的个数。

每个司机从一个站点出发,沿一条线路循环开着。在起点时每个司机都带有一个消息。当司机们在一个站点相遇时,他们互相告知其他人他所知道的消息。问给定一个状况,司机们是不是能够知道所有的消息 。

 

输入:

多case,每个case格式是:

n d s   //代表n条线路,d个司机,s个站点。输入0 0 0 结束。

//接下来,有2n行。分别对应第i个线路 ,及该线路上的司机 ,以该线路的哪个站点为起点 。

//第i个线路情况的输入

a1 a2 a3 ...//不定数,表示该线路的站点

si  di//不定组,表示第si个站点是第di个司机的起始点。

 

输出:

如果司机们能够知道所有人的消息,则输入"Yes",否则输出"No"

 

注意:

1.如果一名司机知道了甲司机的情况。则与乙相遇时,则自己所知道的所有消息都告诉乙(即是自己和甲的消息)

2.每条线路是循环开的。即是最后一个站点是与第一个站点相连的.

 

思路:

主要是用了暴力的搜索,因为数据量不大。过程中,遇到要解模方程的,鉴于数据量不大,用了一个遍历,减少了代码量。主要说明代码中有体现。这道关键是数据结构的,要组织好数据。

 

AC代码:

  1. #include<iostream>
  2. #include<cstdio>   //poj上要加上这句,不然会CE.
  3. using namespace std;
  4.  
  5. int n,m,k; // n是线路 ,m是司机人数 ,k是站的个数。
  6.  
  7. int path [ 20 ] [ 30 ]; //path[i]表示第i个路线经过的站点。
  8. int n_path [ 20 ]; //表示第i条路线的站点个数。
  9. int visitor [ 30 ] [ 2 ]; //表示第i个司机在第[0]个起点,在[1]个条线上。
  10. int ans [ 1000 ]; //辅助变量
  11. int visit [ 30 ] [ 30 ]; //表示i是不是得到j的消息 。
  12.  
  13.  
  14. void solve ( int s, int t )
  15. {
  16. int i,j;
  17. int check;
  18. //检查i,j所在线上有没有相同的起点。check来标志
  19. int p=visitor [s ] [ 1 ]; //s的所在线
  20. int q=visitor [t ] [ 1 ]; //t的所在线。
  21. int starts=visitor [s ] [ 0 ]; //s的起点
  22. int startt=visitor [t ] [ 0 ]; //t的起点。
  23. if (p==q )
  24. {
  25. if (starts==startt )
  26. {
  27. check= 1;
  28. }
  29. else return;
  30. }
  31. else
  32. {
  33. check= 0;
  34. for (i= 0;i<n_path [p ];i++ )
  35. {
  36. for (j= 0;j<n_path [q ];j++ )
  37. {
  38. if (path [p ] [i ]==path [q ] [j ] )
  39. {
  40. //说明两条线上有相同的站点。
  41. for (k= 0;k< 100;k++ )
  42. {
  43. if ( (path [p ] [ (starts+k )%n_path [p ] ]==path [p ] [i ] )
  44. && (path [q ] [ (startt+k )%n_path [q ] ]==path [p ] [i ] ) )
  45. {
  46. check= 1;
  47. break;
  48. }
  49. }
  50. if (check== 1 ) break;
  51. }
  52. }
  53. if (check== 1 ) break;
  54. }
  55. if (check== 0 ) return ;
  56. }
  57. //说明两者相遇
  58. //p与q的所有消息 。
  59.  
  60.  
  61. visit [s ] [t ]= 1;
  62. for (j= 1;j<=m;j++ )
  63. {
  64. if (visit [s ] [j ]== 1||visit [j ] [s ]== 1 )
  65. {
  66. visit [t ] [j ]=visit [j ] [t ]= 1;
  67. }
  68. }
  69.  
  70. visit [t ] [s ]= 1;
  71. for (j= 1;j<=m;j++ )
  72. {
  73. if (visit [t ] [j ]== 1||visit [j ] [t ]== 1 )
  74. {
  75. visit [s ] [j ]=visit [j ] [s ]= 1;
  76. }
  77. }
  78. }
  79.  
  80.  
  81.  
  82. int main ( )
  83. {
  84. char str [ 100 ];
  85. int i,j,k;
  86. int num;
  87. int s;
  88. while (cin>>n>>m>>k )
  89. {
  90. if (n== 0&&m== 0&&k== 0 ) break;
  91. getchar ( );
  92. //初始化
  93. for (i= 1;i<=m;i++ )
  94. {
  95. for (j= 1;j<=m;j++ )
  96. {
  97. if (i==j ) visit [i ] [j ]= 1;
  98. else visit [i ] [j ]= 0;
  99. }
  100. }
  101. for (i= 0;i<n;i++ )
  102. {
  103. //输入站点 的。
  104. gets (str );
  105. n_path [i ]= 0;
  106. k= 0;
  107. s= 0;
  108. for (j= 0;str [j ]!= '/0';j++ )
  109. {
  110. if (str [j ]== ' ' )
  111. {
  112. path [i ] [n_path [i ] ]=s;
  113. n_path [i ]++;
  114. s= 0;
  115. }
  116. else
  117. {
  118. s=str [j ]- '0'+s* 10;
  119. }
  120. }
  121. path [i ] [n_path [i ] ]=s;
  122. n_path [i ]++;
  123. gets (str );
  124. num= 0;
  125. s= 0;
  126. for (j= 0;str [j ]!= '/0';j++ )
  127. {
  128. if (str [j ]== ' ' )
  129. {
  130. ans [num++ ]=s;
  131. s= 0;
  132. }
  133. else s=str [j ]- '0'+s* 10;
  134. }
  135. ans [num++ ]=s;
  136. for (j= 0;j<num;j+= 2 )
  137. {
  138. for (k= 0;k<n_path [i ];k++ )
  139. {
  140. if (ans [j ]==path [i ] [k ] ) {ans [j ]=k;break; }
  141. }
  142. visitor [ans [j +1 ] ] [ 0 ]=ans [j ];
  143. visitor [ans [j +1 ] ] [ 1 ]=i;
  144. }
  145. }
  146. // for(i=1;i<=m;i++) cout<<visitor[i][0]<<" "<<visitor[i][1]<<endl;
  147.  
  148. /// 解决输入问题。下面解决问题。
  149. for (i= 1;i<=m;i++ ) //看i能不能得到j的消息 。
  150. {
  151. for (j=i +1;j<=m;j++ )
  152. {
  153. //判断i是不是能得到j的消息 。
  154. solve (i,j );
  155. }
  156. }
  157. int key= 1;
  158. for (i= 1;i<=m;i++ )
  159. {
  160. for (j= 1;j<=m;j++ )
  161. {
  162. if (visit [i ] [j ]== 0 ) {key= 0;break; }
  163. }
  164. if (key== 0 ) break;
  165. }
  166. if (key ) cout<< "Yes"<<endl;
  167. else cout<< "No"<<endl;
  168. }
  169. return 0;
  170. }
  171.  

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值