闲话:
今天做一问一答的在线编程题目玩,小记如下。
算是给我以后写的文档也整理一下思路,最好也能够帮到正在学习编程的朋友们。
链接:http://wenda60.com/programs/index.html
前四个题没有什么难度,很快就做出来了。但是我的“纯在线编程”(不用本地编译器,不调试,直接编码运行),还是有点挑战的,各种小错误,也是因为我嫌机器慢没有开IDE。
第5个题顶不住了,开IDE调试。
题目3.1 小兔齐齐跑无向图:
详细问题链接:http://wenda60.com/programs/view/id-548.html
给定一个无向图,小兔齐齐一开始位于某个节点上(我们不知道他具体在哪个节点上)。我们知道每一秒小兔都必定会向他所在的节点的某一个邻居节点出发(如果存在邻居节点;假设小兔的移动速度很快,移动时间可以忽略)。在每一秒你可以做不超过2次的询问,每次可以询问某个节点是否有小兔!
现在假设小兔不想被我们找到,同时小兔非常聪明,那么我们需要至少几秒才能必定找到小兔的位置?
Input:输入数据第一行包含一个整数T,表示测试数据的组数。对于每组测试数据: 第一行输入两个整数N和M , N图中的节点,M表示边数,1 <= N <= 15 ,1 <= M <= 100 。 接下来输入M行,每行2个正整数 x y, 表示x和y直接有一条边(不存在自环)。 1<=x,y<=N Output:对于每组数据输出一行,如果你最终可以找到小兔,输出最坏情况下需要几秒才能知道小兔的目前位置;否则输出一个 "-1" (不包括引号) 。
Sample Input
2
3 3
1 2
2 3
3 1
4 3
1 2
2 3
3 1
Sample Output
1
2
Hint
第一组样例中: 第1秒查询节点1和2,如果小兔在1或2,则解决;否则小兔必然在3;
第二组样例中: 第1秒查询节点1和2,如果小兔在1或2,则解决;否则小兔可能在3或者4。第2秒查询节点1和2,如果在1或者2,则解决;否则小兔必然在4(如果前1秒是在节点3,那么这一秒肯定不在1就在2)。
分析:
代码:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
int T,m,n;
bool map[16][16];
int component[16]; //index is node #
int component_size[16];//index is component #
int set_cpnt(const int p,const int cn){
int res=1;
for(int i=1;i<=n;i++){
if(map[p][i] && component[i]!=cn){
component[i]=cn;
res+=set_cpnt(i,cn);
}
}
return res;
}
int max_ring_size=0;
int vis[16];
void largest_ring(const int from, const int p,const int d){
vis[p]=d;
for(int i=1;i<=n;i++){
if(!map[p][i])
continue;
if(vis[i]==0)
largest_ring(p,i,d+1);
else{
int t=vis[p]-vis[i]+1;
max_ring_size=max(max_ring_size,t);
}
}
}
int cal_steps(const int cn){
int res=0;
for(int i=1;i<=cn;i++){
if(component_size[i]<=2)
res++;
else
//it takes k-1 steps to find out whether the rabbit is in a reslovable component with k nodes
res+=component_size[i]-1;
}
return max(1,res-1);
//"res-1" for the global last step, (we can induce it without doing it)
//"max(1,..)" for only one component with less than 2 nodes situation.
}
int main()
{
char sysInputFile[] = "{sysFileUrl}";
ifstream cin(sysInputFile);
cin>>T;
while(T--){
cin>>n>>m;
max_ring_size=0;
memset(vis,0,sizeof(vis));
memset(map,false,sizeof(map));
for(int i=1;i<=n;i++){
component[i]=component_size[i]=0;
}
while(m--){
int a,b;
cin>>a>>b;
map[a][b]=map[b][a]=true;
}
int cn=1;//component number
for(int i=1;i<=n;i++){
if(component[i]==0){
component[i]=cn;
component_size[i]=set_cpnt(i,cn++);
largest_ring(0,i,1);
}
}
cn--;
//there is cn components
int res=0;
if(max_ring_size>3)
cout<<-1<<endl;
else
cout<<cal_steps(cn)<<endl;
}
return 0;
}