• UVA


    /*
      小白书上给出了代码,但是对于代码的解释,不是特别详细,这个博客就比较详细,基本写出了几种分类的依据和考虑,以及如何对于哪些情况,要特别拿出来特判
      博客:
      http://blog.csdn.net/acmore_xiong/article/details/47753589
      
    
      注意:
      1. 虽然小白书上定义的数组名是 left 和 right ,但是不太建议用这两个,因为小白书给出的是C的代码,但如果用到C++  left和right会和 <iostream>头文件中,用于控制IO输入输出格式的 left 和 out 同名,引起二义性,可以将数组名改为大写来解决这个问题
      
      或者,就不用<iostream>头文件了,这题用它主要是想运用自带的swap函数,但是如果只包含 <algorithm>头文件,也能达到同样的效果
      
      
      收获:(具体见小白书P145-148)
      1. 双向链表等复杂的链式结构中,往往会编写一些辅助函数来设置链接关系,例如该题的 link函数
      
      2. 如果数据结构上某一个操作耗时,可以加标记来处理,而不用真的执行那个操作。但同时,该数据结构所有其他操作都要考虑这个标记
      
      3. 复杂链式结构往往容易写错,编码结束后,为了确保程序准确性,测试和调试往往要交替进行
      
      4. 对拍--对于某份可能出错的程序,应该再编写一份速度可能不优,但正确性能得到绝对保证的另一份代码。利用数据生成器(随机数生成函数等),来生成随机数据,执行两个程序,比较它们的结果(简易版本越简单越好,不重在速度,重在正确性)
      
      5.
      数据复杂性会增大调试难度。找到使程序出错的数据后,应尝试简化数据,或者用更小的参数调用数据生成器,找到更简单的错误数据
      
    */

    
    



    #include <cstdio>
    #include <algorithm> 
    using namespace std;
    const int maxn = 1e5 + 10;
    int left[maxn], right[maxn], n, m;
    
    void link(int L, int R)
    {
    	right[L] = R; left[R] = L;
    }
    
    int main()
    {
    	int kase = 0;
    	while (scanf("%d%d", &n, &m) == 2)
    	{
    		for (int i = 1; i <= n; i++)
    		{
    			left[i] = i - 1;
    			right[i] = (i + 1) % (n + 1);
    		}
    		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;
    				if (op == 1 && left[Y] == X) continue;
    				if (op == 2 && right[Y] == X) continue;
    				//注意:后两条语句一定要放前两条语句的后面
    				//因为我们对 4操作是加了标记的,所以,所有其他操作,都要考虑那个标记的影响,之前满足后两个if还不算,一定要在考虑了4的标记的可能影响以后,仍然满足if,才是真正能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(Y, X); link(X, RY);
    				}
    				else if (op == 3)
    				{
    					if (right[X] == Y)
    					{
    						link(LX, Y); link(Y, X); link(X, RY);
    						//在这种情况下,可画图发现,X == LY, Y == RX,所以这里的X和Y,可以分别用LY和RX替换掉
    					}
    					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];
    			if (i % 2) ans += b;
    		}
    		
    		if (inv && n % 2 == 0) ans = (long long)n * (n + 1) / 2 - ans;
    		printf("Case %d: %lld
    ", ++kase, ans);
    	}
    }


  • 相关阅读:
    Could not get lock /var/lib/apt/lists/lock
    使用vmware提示无法打开内核设备 \.Globalvmx86: 系统找不到指定的文件
    Linux 下安装 MATLAB
    超级干货:Linux常用命令 & 实用命令万字总结!
    GNB 配置图图解
    GNB Linux 部署说明
    解决Firefox启动、打开网页慢、占用内存多
    【Git教程】如何清除git仓库的所有提交记录,成为一个新的干净仓库
    mount --bind和硬连接的区别
    彻底删除 Windows Defender
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789406.html
Copyright © 2020-2023  润新知