zoukankan      html  css  js  c++  java
  • Boxes in a Line UVA

    题目链接:https://vjudge.net/problem/UVA-12657

    题目大意:输入n,m  代表有n个盒子 每个盒子最开始按1~n排成一行  m个操作,

    1 x y  :把盒子x放到y的左边

    2 x y: 把盒子x放到y 的右边

    3 x y:调换x y盒子的位置

    4    表示反转整条链

    思路:也是很明显的暴力 模拟 。  但是值得提的是 虽然是暴力,但是却是用的双向链表来暴力。  

    有很多要注意的地方 :

    当操作4的时候,我们可以把本次操作记录一下,不必直接把全部的位置反转 试想一下,如果每次出现一个4  每次都反转  那多麻烦 (我们要反转的话,首先得找到最后一个盒子,然后从最后一个盒子往前重新存储一遍)

    但是如果有记录操作4注意再碰到其他操作 也要随之改变  :

    当有记录4的时候  操作1就相当于操作2     操作2相当于操作1  

    还有注意的是  操作3  两个盒子交换位置   :  两个盒子相邻和不相邻是不一样的  切记!!!

    最后   要输出结果的话 :  注意有没有操作4  如果有操作4的话  如果是奇数 反转一次对结果没有影响   但是偶数 的话    反转一次 我们现在求的刚好的偶数位的   总的减掉就是答案了

    具体看代码:

    #include<iostream>
    #include<string.h>
    #include<vector>
    #include<stdio.h>
    using namespace std;
    const int maxn=1e5+5;
    int n;
    int Left[maxn];
    int Right[maxn];
    void link(int l,int r) //两个节点相连
    {
        Right[l]=r;
        Left[r]=l;
    }
    int main()
    {
        int m,ca=0;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=1;i<=n;i++)//存好节点
            {
                Left[i]=i-1;
                Right[i]=(i+1)%(n+1);//这里为何%(n+1)   试想一下 最后一个元素的右端是谁   显然是第一个元素0
            }
            Left[0]=n;
            Right[0]=1;
            int op,x,y,inv=0;
            while(m--)
            {
                scanf("%d",&op);
                if(op==4) inv=!inv;//相当于一种延迟标记  
                else
                {
                    scanf("%d%d",&x,&y);
                    if(op==3&&Right[y]==x) swap(x,y);//
                    if(op!=3&&inv) op=3-op;//当调整一次顺序的时候 操作1和2  刚好相反 可以自己举例子
                    if(op==1&&x==Left[y]) continue;//已经满足条件了
                    if(op==2&&x==Right[y]) continue;
                    int lx=Left[x],rx=Right[x],ly=Left[y],ry=Right[y];
                    if(op==1) //调整位置
                    {
                        link(lx,rx);
                        link(ly,x);
                        link(x,y);
                    }
                    else if(op==2)
                    {
                        link(lx,rx);
                        link(x,ry);
                        link(y,x);
                    }
                    else if(op==3)//注意两者相连和不相连交换位置操作是不一样的  !!!
                    {
                        if(Right[x]==y) //
                        {
                            link(lx,y);
                            link(y,x);
                            link(x,ry);
                        }
                        else
                        {
                            link(lx,y);
                            link(y,rx);
                            link(ly,x);
                            link(x,ry);
                        }
                    }
                }
    
    
            }
            int b=0;
            long long ans=0;
            for(int i=1;i<=n;i++)
            {
                b=Right[b];//其实b就是i位置对应的值  可以仔细想一下
                if(i%2==1) ans+=b;
            }
            if(inv&&n%2==0) ans=(long long)n*(n+1)/2-ans;//自己举个例子就可以明白 n为奇数没有影响
            printf("Case %d: %lld
    ",++ca,ans);
        }
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    学习手机安全卫士项目源码记录(一)
    AIDL Service
    让一个Activity在开机后自动显示
    如何拦截手机屏幕休眠和唤醒动作
    润前报表简单问题
    javaEE框架的session获取
    UEditer使用
    jQuery动态绑定生成的元素
    javadoc 生成乱码
    个人异常收集_SE_EE_WEB...
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10345830.html
Copyright © 2011-2022 走看看