<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      UVa12657移動(dòng)盒子

      當(dāng)插入刪除搬家移動(dòng)位置比較多的時(shí)候,普通數(shù)組必定超時(shí),此時(shí)在數(shù)據(jù)結(jié)構(gòu)上考慮優(yōu)化,用鏈表。

      要知道盒子的前驅(qū)和后繼,采用雙向鏈表。

      結(jié)點(diǎn)類三個(gè)成員,左指針、右指針、數(shù)據(jù)值。指針是數(shù)組下標(biāo)。

      因?yàn)樵擃}目是根據(jù)數(shù)據(jù)值來(lái)移動(dòng),而不是數(shù)據(jù)值的位置,所以最好是把數(shù)據(jù)值就當(dāng)作數(shù)組下標(biāo),直接將元素對(duì)應(yīng)到房間下標(biāo)。因此結(jié)點(diǎn)類就不需要3個(gè)成員,只需要2個(gè)。

      此外,仍然用0號(hào)代表頭結(jié)點(diǎn),初始化first指針指向0號(hào),頭結(jié)點(diǎn)的右指針指向第一個(gè)實(shí)際元素,頭結(jié)點(diǎn)的左指針指向最后一個(gè)元素。維護(hù)last指針指向最后一個(gè)元素,最后一個(gè)元素的左指針指向前驅(qū),右指針指向頭結(jié)點(diǎn)。

      操作3——交換位置

      畫個(gè)圖就知道如何寫了,而且還要確定好執(zhí)行順序。

      void SWAP(int a, int b) { // 交換位置 
      	rlink[llink[a]] = b;
      	llink[rlink[a]] = b;
      	
      	rlink[llink[b]] = a; 
      	llink[rlink[b]] = a;
      	
      	int t = rlink[b];
      	rlink[b] = rlink[a];
      	rlink[a] = t;
      	 
      	t = llink[b];
      	llink[b] = llink[a];
      	llink[a] = t;	
      	return;
      }
      

      這種寫法對(duì)于一般的情況是可以的,但是對(duì)于相鄰的情況來(lái)說就會(huì)出現(xiàn)問題,就會(huì)出現(xiàn)自己的左右指針指向自己的情況。因此數(shù)據(jù)結(jié)構(gòu)上的操作要考慮完整。以上代碼交上去得了一個(gè)超時(shí),幸好有一組測(cè)試數(shù)據(jù)對(duì)應(yīng)到了超時(shí)的這種情況。

      4 1
      3 3 4

      這組數(shù)據(jù)遲遲不能出結(jié)果。陷入了死循環(huán),交換寫得有問題。特殊情況的考慮要貫穿所有操作。

      這兩種寫法不能合并。3種情況合成2種就是讓鏈上位于左邊的數(shù)在前面,視情況交換a和b。

      if (llink[a] == b) { 
          int t = a;
          a = b;
          b = t;
      }
      

      !> 值突然改變要么就是越界要么就是==寫成=。

      不相鄰情況:
      a->llink->rlink=b
      a->rlink->llink=b
      b->rlink->llink=a
      b->llink->rlink=a
      // 三變量交換,這里是直觀寫法
      a->rlink=b->rlink
      b->rlink=a->rlink
      // 三變量交換,這里是直觀寫法
      a->llink=b->llink
      b->llink=a->llink
      
      相鄰情況:
      a->llink->rlink=b
      b->rlink->rllink=a
      a->rlink=b->rlink
      b->llink=a->llink
      b->rlink=a
      a->llink=b
      
      操作4——反轉(zhuǎn)整條鏈

      反轉(zhuǎn)整條鏈,將last指針和頭結(jié)點(diǎn)指針對(duì)調(diào)。但是這樣還不夠,2、3操作涉及把盒子移動(dòng)到左邊右邊,如果反轉(zhuǎn)了,左邊右邊關(guān)系就改變了,如果對(duì)每個(gè)結(jié)點(diǎn)對(duì)調(diào)左右指針會(huì)比較麻煩和費(fèi)時(shí)。因此引入一個(gè)標(biāo)記,一旦引入這個(gè)標(biāo)記,其他操作都要考慮這個(gè)標(biāo)記。線段樹的懶標(biāo)記也是引入標(biāo)記。

      提示6-6非常核心:

      如果數(shù)據(jù)結(jié)構(gòu)上的某一個(gè)操作很耗時(shí),有時(shí)可以用加標(biāo)記的方式處理,而不需要真的執(zhí)行那個(gè)操作。但同時(shí),該數(shù)據(jù)結(jié)構(gòu)的所有其他操作都要考慮這個(gè)標(biāo)記。

      如果a在b左邊,反轉(zhuǎn)整條鏈,a就在b的右邊。如果a要放到b的左邊,反轉(zhuǎn)整條鏈就是把a(bǔ)放到b的右邊。

      例子:1 a b

      • 沒有反轉(zhuǎn) 執(zhí)行前 a <-> c <-> d <-> b 執(zhí)行后 c <-> d <-> a <-> b
      • 有反轉(zhuǎn) 執(zhí)行前 b <-> d <-> c <-> a 執(zhí)行后 a <-> b <-> d <-> c

      ? 再把這個(gè)執(zhí)行結(jié)果反轉(zhuǎn)回去就是c <-> d <-> b <-> a,相當(dāng)于沒有反轉(zhuǎn) 2 a b

      ? 因此如果有反轉(zhuǎn),輸出的時(shí)候也要反轉(zhuǎn)。

      求奇數(shù)位置的盒子編號(hào)就挨著走鏈,直到指回頭結(jié)點(diǎn)。

      如果是盒子總數(shù)是奇數(shù),反轉(zhuǎn)就不影響結(jié)果,如果盒子總數(shù)是偶數(shù),反轉(zhuǎn)就是取補(bǔ)。注意最大50億超了int。注意修改數(shù)據(jù)類型則所有地方,包括輸入輸出都要改。涉及l(fā)ong long就要隨時(shí)注意類型轉(zhuǎn)換,還有防止溢出的問題。

      #include <cstdio>
      #include <cstring>
      #include <algorithm>
      using namespace std;
      const int MAXN = 100010;
      
      int llink[MAXN];
      int rlink[MAXN];
      int first, last;
      int inv; // 反轉(zhuǎn)標(biāo)記 
      int n, m;
      void Init(int n) {
      	inv = 0;
      	first = 0;
      	last = n;
      	for(int i = 1; i < MAXN - 1; i++) { // 從1開始沒有給0弄到 
      		llink[i] = i - 1;
      		rlink[i] = i + 1;
      	}
      	rlink[0] = 1; 
      	rlink[n] = 0;
      	return;
      }
      
      void SWAP(int a, int b) { // 交換位置
      	if (llink[a] == b || rlink[a] == b) {
      		//3種寫法變成2種寫法就是使得位于左邊的數(shù)在前面,交換a和b。
      		if (llink[a] == b) { 
      			int t = a;
      			a = b;
      			b = t;
      		}
      		rlink[llink[a]] = b;
      		llink[rlink[b]] = a; 
      		rlink[a] = rlink[b];
      		llink[b] = llink[a];
      		
      		rlink[b] = a;
      		llink[a] = b;	
      	} else {
      		rlink[llink[a]] = b;
      		llink[rlink[a]] = b;
      		
      		rlink[llink[b]] = a; 
      		llink[rlink[b]] = a;
      		
      		int t = rlink[b];
      		rlink[b] = rlink[a];
      		rlink[a] = t;
      		 
      		t = llink[b];
      		llink[b] = llink[a];
      		llink[a] = t;			
      	}
      
      	return;
      }
      
      void InsertToLeft(int a, int b) { // 將a移動(dòng)到b左邊 
      	rlink[llink[a]] = rlink[a];
      	llink[rlink[a]] = llink[a];
      	
      	rlink[llink[b]] = a;
      	
      	llink[a] = llink[b];
      	rlink[a] = b;
      	llink[b] = a;
      	
      	return;
      }
      
      void InsertToRight(int a, int b) { // 將a移動(dòng)到b右邊
      	rlink[llink[a]] = rlink[a];
      	llink[rlink[a]] = llink[a];
      	
      	llink[rlink[b]] = a;
      	
      	rlink[a] = rlink[b];
      	llink[a] = b;
      	rlink[b] = a;
      	
      	return;
      }
      
      int main() {
      	freopen("data.in", "r", stdin);
      	
      	
      	
      	
      	int k = 0;
      	while (scanf("%d%d", &n, &m) == 2) {
      		Init(n);
      		for (int i = 0; i < m; i++) {
      			int op = 0;
      			scanf("%d", &op);
      			if (op == 4) { // 反轉(zhuǎn)整條鏈 
      				if (inv == 1) {
      					inv = 0;
      				} else {
      					inv = 1;
      				}
      			} else if (op == 3) { // 交換位置 
      				int a, b;
      				scanf("%d%d", &a, &b);			
      				SWAP(a, b);
      			} else { // 移動(dòng)到左邊或者右邊 
      				if (inv == 1) {
      					op = 3 - op;
      				}
      				int a, b;
      				scanf("%d%d", &a, &b);
      				if (op == 1) { // 將a移動(dòng)到b左邊 
      					if (llink[b] == a) {
      						continue;
      					}
      					InsertToLeft(a, b); 
      				} else {
      					if (rlink[b] == a) {
      						continue;
      					}
      					InsertToRight(a, b); // 將a移動(dòng)到b右邊 
      				}
      			}
      		}
      		
      		long long ans = 0; // 最大的50億超了int 
      		int cur = rlink[0]; // 指向第一個(gè)元素 
      		int i;
      		for (i = 1; cur != 0; i++) {
      			if (i % 2 == 1) {
      				ans += cur;
      			}
      			cur = rlink[cur];
      		}
      		if (inv == 1 && n % 2 == 0) {
      			ans = (long long)(n + 1) * (n / 2) - ans; 
      		}
      		printf("Case %d: %lld\n", ++k, ans);
      	}
      	return 0;
      }
      
      posted @ 2021-02-15 10:49  Mo_hw  閱讀(167)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 精品久久久无码中文字幕| 神马午夜久久精品人妻| 滦南县| 大陆一级毛片免费播放| 久久亚洲人成网站| 久久精品国产亚洲av麻| 亚洲第一区二区快射影院| 久久精品国产亚洲精品色婷婷| 国产一区二区三区不卡自拍| 欧美亚洲一区二区三区在线| 亚洲欧美日韩综合久久| 国产伦精区二区三区视频| 日韩av一区二区三区不卡| 欧洲码亚洲码的区别入口| 国产成AV人片久青草影院| 色综合色综合久久综合频道88| 高清美女视频一区二区三区| 99国产欧美另类久久久精品| 久久香蕉国产线看观看猫咪av| 亚洲欧美人成人让影院| 中文字幕理伦午夜福利片| 精品久久一线二线三线区| 国产久免费热视频在线观看| 疯狂做受XXXX高潮国产| 亚洲AV成人片在线观看| 中文字幕人妻无码一夲道| 久久精品国产99亚洲精品| 丝袜老师办公室里做好紧好爽 | 久久国产精品老女人| 无码人妻斩一区二区三区| 国产精品一区二区三区麻豆| 久久久久成人精品无码中文字幕| 免费大黄网站在线观看| 亚洲午夜无码久久久久蜜臀av| 久久99久久99精品免观看| 午夜精品一区二区三区在线观看 | 一本加勒比hezyo无码人妻| 亚洲国产精品第一区二区| 国产三级国产精品国产专| 国产精品天天看天天狠| 摸丰满大乳奶水www免费|