zoukankan      html  css  js  c++  java
  • APIO2007风铃

    描述

    你准备给弟弟Ike 买一件礼物,但是,Ike 挑选礼物的方式很特别:他只喜欢那些能按照他的特有方式排成有序的东西。

    你准备给Ike 买一个风铃。风铃是一种多层的装饰品,一般挂在天花板上。 每个风铃都包含一些由竖直的线连起来的水平杆。每根杆的两端都有线连接,下 面或者挂着另一根水平杆,或者挂着一个玩具。下面是一个风铃的例子:

    20170518163245_87667

    为使你的弟弟满意,你需要选一个满足下面两个条件的风铃:

    (1) 所有的玩具都在同一层(也就是说,每个玩具到天花板之间的杆的个数是 一样的)或至多相差一层。

    (2) 对于两个相差一层的玩具,左边的玩具比右边的玩具要更靠下一点。

    风铃可以按照下面的规则重新排列:任选一根杆,将杆两端的线“交换”。

    也就是解开一根杆左右两端的线,然后将它们分别绑到杆的另一端。注意这个操 作不会改变下面的杆上线的排列顺序。

    由于你正在参加信息学奥林匹克的训练,所以你决定设计一个算法,判断能 否通过重新排列,将一个给定的风铃变为Ike 喜欢的样子。

    考虑上面的例子,上图中的风铃满足条件(1),却不满足条件(2)——最左边 的那个玩具比它右边的要高。

    但是,我们可以通过下面的步骤把这个风铃变成一个Ike 喜欢的形式:

    1. 第一步,将杆1 的左右两端交换,这使得杆2 和杆3 的位置互换,交换 的结果如下图所示:APIO2007-1-2
      1. 第二步,也是最后一步,将杆2 的左右两端交换,这使得杆4 到了左边, 原来在左边的玩具到了右边,交换的结果如下图所示: APIO2007-1-3

        现在这个风铃就满足Ike 的条件了。

    你的任务是:给定一个风铃的描述,求出最少需要多少次交换才能使这个风 铃满足Ike 的条件(如果可能的话)。

    输入

    输入的第一行包含一个整数n (1≤n ≤ 1 00 000),表示风铃中有多少根杆。

    接下来的n 行描述杆的连接信息。这部分的第i 行包含两个由空格分隔的整

    数l 和r ,描述杆i 的左右两端悬挂的东西。如果挂的是一个玩具,则对应的值 i i

    为-1,否则为挂在下面的杆的编号。

    如果杆i 下面挂有其它杆,则这些杆的编号将严格大于i。杆1 位于风铃的 顶部。

    输出

    输出仅包含一个整数。表示最少需要多少次交换能使风铃满足Ike 的条件。

    如果不可能满足,输出-1。

    样例输入[复制]
    6
    2 3 
    -1 4 
    5 6 
    -1 -1 
    -1 -1 
    -1 -1
    样例输出[复制]
    2
     
     
    这题很迷啊,好像就是个贪心的搜索
    首先判断深度一次dfs就搞完了,差大于1直接输出-1
    然后至于交换的话,如果左右子树都是有深有浅那么就输出-1
    搜索的时候一个变量记录一下当前子树的情况,0代表全是浅的,1代表全是深的
    然后几个判断就没有了,第一次还做不出来。。。。。菜啊
    code:
     1 #include<iostream>
     2 #include<cstdio>
     3 #define N 1000006
     4 #include<algorithm>
     5 using namespace std;
     6 struct node{
     7     int lc,rc;
     8 }t[N];
     9 int n;
    10 int dep[N],now,max0,min0=999999999,fa[N],ans=0;
    11 void dfs(int x){
    12     if(x>n)max0=max(max0,dep[x]),min0=min(min0,dep[x]);
    13     dep[t[x].lc]=dep[t[x].rc]=dep[x]+1;
    14     if(t[x].lc)dfs(t[x].lc);
    15     if(t[x].rc)dfs(t[x].rc); 
    16 }
    17 int solve(int x,int s){
    18     if(x>n){
    19         if(s==min0)return 0;
    20         return 1;
    21     }
    22     int a,b;
    23     a=solve(t[x].lc,s+1);
    24     b=solve(t[x].rc,s+1);
    25     if((a==0&&b==1)||(a==2&&b==1)||(a==0&&b==2))ans++;
    26     if(a==2&&b==2){
    27         cout<<-1;
    28         exit(0);
    29     }
    30     if((a==0&&b==1)||(a==1&&b==0))return 2;
    31     if(a==0&&b==0)return 0;
    32     if(a==1&&b==1)return 1;
    33     return 2; 
    34 }
    35 int main(){
    36     cin>>n;
    37     now=n;
    38     for(int i=1;i<=n;i++){
    39         cin>>t[i].lc>>t[i].rc;
    40         if(t[i].lc==-1)t[i].lc=++now;
    41         if(t[i].rc==-1)t[i].rc=++now;
    42         fa[t[i].lc]=fa[t[i].rc]=i;
    43     }
    44     dep[1]=1;
    45     dfs(1);
    46     if(max0-min0>1){
    47         cout<<-1;
    48         return 0;
    49     }
    50     if(max0==min0){
    51         cout<<0;
    52         return 0;
    53     }
    54     solve(1,1);
    55     cout<<ans;
    56     return 0;
    57 } 
  • 相关阅读:
    Ext JS学习第三天 我们所熟悉的javascript(二)
    Ext JS学习第二天 我们所熟悉的javascript(一)
    Ext JS学习第十七天 事件机制event(二)
    Ext JS学习第十六天 事件机制event(一)
    Ext JS学习第十五天 Ext基础之 Ext.DomQuery
    Ext JS学习第十四天 Ext基础之 Ext.DomHelper
    Ext JS学习第十三天 Ext基础之 Ext.Element
    Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)
    针对错误 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 的原因分析
    C# 使用HttpWebRequest通过PHP接口 上传文件
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9681713.html
Copyright © 2011-2022 走看看