下面是近期解决的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代码:
-
#include<iostream>
-
#include<cstdio> //poj上要加上这句,不然会CE.
-
using
namespace std;
-
-
int n,m,k;
// n是线路 ,m是司机人数 ,k是站的个数。
-
-
int path
[
20
]
[
30
];
//path[i]表示第i个路线经过的站点。
-
int n_path
[
20
];
//表示第i条路线的站点个数。
-
int visitor
[
30
]
[
2
];
//表示第i个司机在第[0]个起点,在[1]个条线上。
-
int ans
[
1000
];
//辅助变量
-
int visit
[
30
]
[
30
];
//表示i是不是得到j的消息 。
-
-
-
void solve
(
int s,
int t
)
-
{
-
int i,j;
-
int check;
-
//检查i,j所在线上有没有相同的起点。check来标志
-
int p=visitor
[s
]
[
1
];
//s的所在线
-
int q=visitor
[t
]
[
1
];
//t的所在线。
-
int starts=visitor
[s
]
[
0
];
//s的起点
-
int startt=visitor
[t
]
[
0
];
//t的起点。
-
if
(p==q
)
-
{
-
if
(starts==startt
)
-
{
-
check=
1;
-
}
-
else
return;
-
}
-
else
-
{
-
check=
0;
-
for
(i=
0;i<n_path
[p
];i++
)
-
{
-
for
(j=
0;j<n_path
[q
];j++
)
-
{
-
if
(path
[p
]
[i
]==path
[q
]
[j
]
)
-
{
-
//说明两条线上有相同的站点。
-
for
(k=
0;k<
100;k++
)
-
{
-
if
(
(path
[p
]
[
(starts+k
)%n_path
[p
]
]==path
[p
]
[i
]
)
-
&&
(path
[q
]
[
(startt+k
)%n_path
[q
]
]==path
[p
]
[i
]
)
)
-
{
-
check=
1;
-
break;
-
}
-
}
-
if
(check==
1
)
break;
-
}
-
}
-
if
(check==
1
)
break;
-
}
-
if
(check==
0
)
return ;
-
}
-
//说明两者相遇
-
//p与q的所有消息 。
-
-
-
visit
[s
]
[t
]=
1;
-
for
(j=
1;j<=m;j++
)
-
{
-
if
(visit
[s
]
[j
]==
1||visit
[j
]
[s
]==
1
)
-
{
-
visit
[t
]
[j
]=visit
[j
]
[t
]=
1;
-
}
-
}
-
-
visit
[t
]
[s
]=
1;
-
for
(j=
1;j<=m;j++
)
-
{
-
if
(visit
[t
]
[j
]==
1||visit
[j
]
[t
]==
1
)
-
{
-
visit
[s
]
[j
]=visit
[j
]
[s
]=
1;
-
}
-
}
-
}
-
-
-
-
int main
(
)
-
{
-
char str
[
100
];
-
int i,j,k;
-
int num;
-
int s;
-
while
(cin>>n>>m>>k
)
-
{
-
if
(n==
0&&m==
0&&k==
0
)
break;
-
getchar
(
);
-
//初始化
-
for
(i=
1;i<=m;i++
)
-
{
-
for
(j=
1;j<=m;j++
)
-
{
-
if
(i==j
) visit
[i
]
[j
]=
1;
-
else visit
[i
]
[j
]=
0;
-
}
-
}
-
for
(i=
0;i<n;i++
)
-
{
-
//输入站点 的。
-
gets
(str
);
-
n_path
[i
]=
0;
-
k=
0;
-
s=
0;
-
for
(j=
0;str
[j
]!=
'/0';j++
)
-
{
-
if
(str
[j
]==
' '
)
-
{
-
path
[i
]
[n_path
[i
]
]=s;
-
n_path
[i
]++;
-
s=
0;
-
}
-
else
-
{
-
s=str
[j
]-
'0'+s*
10;
-
}
-
}
-
path
[i
]
[n_path
[i
]
]=s;
-
n_path
[i
]++;
-
gets
(str
);
-
num=
0;
-
s=
0;
-
for
(j=
0;str
[j
]!=
'/0';j++
)
-
{
-
if
(str
[j
]==
' '
)
-
{
-
ans
[num++
]=s;
-
s=
0;
-
}
-
else s=str
[j
]-
'0'+s*
10;
-
}
-
ans
[num++
]=s;
-
for
(j=
0;j<num;j+=
2
)
-
{
-
for
(k=
0;k<n_path
[i
];k++
)
-
{
-
if
(ans
[j
]==path
[i
]
[k
]
)
{ans
[j
]=k;break;
}
-
}
-
visitor
[ans
[j
+1
]
]
[
0
]=ans
[j
];
-
visitor
[ans
[j
+1
]
]
[
1
]=i;
-
}
-
}
-
// for(i=1;i<=m;i++) cout<<visitor[i][0]<<" "<<visitor[i][1]<<endl;
-
-
/// 解决输入问题。下面解决问题。
-
for
(i=
1;i<=m;i++
)
//看i能不能得到j的消息 。
-
{
-
for
(j=i
+1;j<=m;j++
)
-
{
-
//判断i是不是能得到j的消息 。
-
solve
(i,j
);
-
}
-
}
-
int key=
1;
-
for
(i=
1;i<=m;i++
)
-
{
-
for
(j=
1;j<=m;j++
)
-
{
-
if
(visit
[i
]
[j
]==
0
)
{key=
0;break;
}
-
}
-
if
(key==
0
)
break;
-
}
-
if
(key
) cout<<
"Yes"<<endl;
-
else cout<<
"No"<<endl;
-
}
-
return
0;
-
}
-