校门外的树

校门外的树

【问题描述】
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。



【输入文件】
输入文件tree.in的第一行有两个整数L(1<= L <= 10000)和M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。



【输出文件】
输出文件tree.out包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。



【样例输入】
500 3

150 300

100 200

470 471



【样例输出】

298

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。



    public int GetTree(int L, Zone[] zones)//效率低下(冒泡法n^2)
    {
        int count = 0;
        for (int i = 0; i < zones.Length; i++)//计算总数(包含重复)
        {
            count += zones[i].End - zones[i].Begin + 1;//包含两端
        }
        for (int i = 0; i < zones.Length - 1; i++)
        {
            for (int j = i + 1; j < zones.Length; j++)
            {
                count -= GetZoneN(zones[i], zones[j]);
            }
        }


        return L - count + 1;


    }


    //取交集个数(其中一个开始端必在另一个区域内)
    public int GetZoneN(Zone z1, Zone z2)
    {
        int count = 0;
        Zone Temp;
        if (z1.Begin >= z2.Begin && z1.Begin <= z2.End)//z1在区域内
        {
            Temp.Begin = z1.Begin;
            Temp.End = z1.End >= z2.End ? z2.End : z1.End;//取小
            count = Temp.End - Temp.Begin + 1;
        }
        if (z2.Begin >= z1.Begin && z2.Begin <= z1.End)//z2在区域内
        {
            Temp.Begin = z2.Begin;
            Temp.End = z2.End >= z1.End ? z1.End : z2.End;//取小
            count = Temp.End - Temp.Begin + 1;
        }


        return count;
    }


    //区域
    public struct Zone
    {
        public int Begin;
        public int End;
    }
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

//基于链表的实现

  public int GetTreeCount(ACMTreeList list, int L)
    {
        //计算移走的树数量
        ACMTreeNode temp = list.Head;
        int count = 0;
        while (temp.Next != null)
        {
            count += temp.Next.End - temp.Next.Begin + 1;
            temp = temp.Next;
        }
        return L + 1 - count;
    }


    //校门外的树链表实现
    public void GetTreeList(ACMTreeList list, ACMTreeNode node)
    {
        //逐个节点比较,有交集则合并,否则直接插入或追加
        ACMTreeNode temp = list.Head;
        if (temp.Next == null)
        {
            temp.Next = node;
        }
        while (temp.Next != null)
        {
            //比较是否有交集
            if (node.End < temp.Next.Begin)//1.直接在左侧插入
            {
                node.Next = temp.Next;
                temp.Next = node;
                break;
            }
            else if (node.Begin > temp.Next.End)//2.在右侧
            {
                temp = temp.Next;//指向下一节点
                if (temp.Next == null)
                {
                    temp.Next = node;
                    break;
                }
            }
            else if (temp.Next.Begin >= node.Begin && temp.Next.Begin <= node.End) //有交集temp在区域内
            {
                temp.Next.Begin = node.Begin;//取小
                temp.Next.End = temp.Next.End >= node.End ? temp.Next.End : node.End;//取大
                break;
            }
            else if (node.Begin >= temp.Next.Begin && node.End <= temp.Next.End)//node在区域内
            {
                temp.Next.End = temp.Next.End >= node.End ? temp.Next.End : node.End;//取大
                break;
            }


        }
    }

//更改1

 public void GetTreeList1(ACMTreeList list, ACMTreeNode node)
    {
        //逐个节点比较,有交集则合并,否则直接插入或追加
        ACMTreeNode temp = list.Head;
        if (temp.Next == null)
        {
            temp.Next = node;
        }


        while (temp.Next != null)
        {
            //比较是否有交集
            if (node.End < temp.Next.Begin)//1.直接在左侧插入
            {
                node.Next = temp.Next;
                temp.Next = node;
                break;
            }
            if (temp.Next.Begin >= node.Begin && temp.Next.Begin <= node.End) //有交集temp在区域内
            {
                temp.Next.Begin = node.Begin;//取小
                temp.Next.End = temp.Next.End >= node.End ? temp.Next.End : node.End;//取大
                break;
            }
            if (node.Begin >= temp.Next.Begin && node.End <= temp.Next.End)//node在区域内
            {
                temp.Next.End = temp.Next.End >= node.End ? temp.Next.End : node.End;//取大
                break;
            }
            if (node.Begin > temp.Next.End)//2.在右侧
            {
                temp = temp.Next;//指向下一节点
                if (temp.Next == null)
                {
                    temp.Next = node;
                    break;
                }
            }


        }
    }


//构造链表

public class ACMTreeList
{
    private ACMTreeNode _Head;
public ACMTreeList()
{
//
//TODO: 在此处添加构造函数逻辑
//
        _Head = new ACMTreeNode();
}


    public ACMTreeNode Head
    {
        get { return _Head; }
        set { _Head = value; }
    }
}

//构造节点

public class ACMTreeNode
{
public ACMTreeNode()
{
        Next = null;
}


    private int _begin;
    private int _end;
    private ACMTreeNode _next;


    public int Begin
    {
        get { return _begin; }
        set { _begin = value; }
    }
    public int End
    {
        get { return _end; }
        set { _end = value; }
    }
    public ACMTreeNode Next
    {
        get { return _next; }
        set { _next = value; }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值