ZJU2016 Play on Words - 有向图的欧拉通路

题目描述:

有n个单词n<100000,单词长度不超过1000,全由小写字母组成。当一个单词的首字母是另一个单词的末尾字母时,可以连接在一起。 要求这些单词能否全部连接在一起。可能出现重复的单词,须多次使用。

分析:

问题简化之后就变成了一个一笔画问题,也就是求一个图是否是存在欧拉通路。只不过这里的图是有向图。

离散数学书里可以找到关于“无向图”欧拉通路的广为人知结论:

无向连通图存在欧拉通路,当且仅当度为奇数的顶点不超过2个。顶点的“度”等于与它相连的边的条数。

特殊地,无向连通图存在欧拉回路,当且仅当所有顶点的度为偶数。

对于此题也不难推得以下结论:

有向连通图存在欧拉通路,当且仅当不超过2个顶点的入度不等于出度,且入度与出度的差不大于1。

可以这样理解:若存在欧拉通路,必然从起点出发,途径若其他所有顶点,最后停留在终点。对于路途中的顶点,必然进去一次就需要出来一次,所以入度必定等于出度;而对于起点和终点,起点的出度比入度大1,终点的入度比出度大1。若有向图是欧拉回路,则所有顶点的入度等于出度。即从任意顶点出发都可以遍历整个图。

写程序的时候不要忘了判断图是否连通。

这里由个优化,可以使用并查集来判断图的连通性,判断时把图当作是无向图来判断。即只需要有向图弱连通即可。

贴一下代码,挺快的~:

#include <stdio.h>
#include <string.h>
#define N 1005
#define clr(a) memset(a,0,sizeof(a))
#define abs(x) ((x)>0?(x):-(x))

int a[30],b[30];
char s[N];
char f[30];

char root(char p){
    int t,q=p;
    while(f[q]) q=f[q];
    while(f[p]){
        t=f[p];
        f[p]=q;
        p=t;
    }
    return q;
}

int main()
{
    int i,j,k,m,n,T;
    int count,flag,con;
    int p,q,r,v='a'-1;
   
    scanf("%d",&T);
    while(T--)
    {
        //init
        clr(a); clr(b);
        clr(f);
       
        //input
        scanf("%d",&n);
        getchar();
        for(i=0;i<n;i++){
            gets(s);
           
            m=strlen(s)-1;
            a[s[0]-v]++;
            b[s[m]-v]++;
           
            p=root(s[0]-v);
            q=root(s[m]-v);
            if(p!=q) f[p]=q;
        }
       
        //connected
        con=1;
        j=1;
        while(!(a[j]+b[j])) j++;
        r=root(j);
        for(i=j;i<=26&&con;i++)
            if((a[i]+b[i])&&root(i)!=r)
                con=0;
       
        //judge
        count=0;
        flag=con;
       
        for(i=1;i<=26&&flag;i++){
            if(a[i]!=b[i]) count++;
            if(count>2||abs(a[i]-b[i])>1) flag=0;
        }
       
        //output
        if(flag&&count<=2) puts("Ordering is possible.");
        else puts("The door cannot be opened.");
    }
   
    //system("pause");
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ZJU-I型机械臂是一种由浙江大学机器人研究所开发的六自由度机械臂,具有高速、精度和可靠性等特点。机械臂的运动控制是机器人中的重要研究领域之一,其中点到点轨迹规划是机器人在运动过程中最基础和常用的一种方式,也是机械臂控制的核心问题之一。 点到点轨迹规划的目标是通过给定的起点和终点,计算出机械臂的运动轨迹,使机械臂在运动过程中满足机械臂轨迹的连续性、平滑性、可控性等要求。在过去的研究中,经典的点到点轨迹规划方法包括插值法、线性规划法、最小能量法等。 如果使用Python实现机械臂的点到点轨迹规划,可以采用Robotics Toolkit(简称robot)这个模块。robot模块提供了各种从轨迹规划、控制到仿真的功能,可用于ROS、Vrep、Webots等机器人仿真软件。使用robot模块,可以通过几行代码实现机械臂的点到点轨迹规划,例如: ``` from roboticstoolkit import robot from roboticstoolkit.robots import zju # 初始化机器人 zju_arm = robot.Robot('zju', zju.URDF) # 设定起点和终点 start = [0, 0, 0, 0, 0, 0] goal = [0, 1, 1, 0.5, 0, 0] # 计算机械臂的轨迹 path = zju_arm.get_trajectory(start, goal) # 控制机械臂运动到终点 zju_arm.move_to(goal) ``` 其中,`roboticstoolkit`和`roboticstoolkit.robots`都是导入的Python模块,`zju`是机械臂的URDF定义文件,`start`和`goal`是起点和终点的坐标,`get_trajectory()`函数会返回计算得到的机械臂轨迹,`move_to()`函数则控制机械臂运动到终点。 总之,使用Python实现ZJU-I型机械臂的点到点轨迹规划相对简单,只需要导入相应的模块,并根据需要设置机械臂的各种参数,即可轻松实现机械臂的控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值