UVA - 12657(双向链表,左插入,右插入,交换,翻转)

版权声明:转载请在原文附上源连接以及作者,谢谢~ https://blog.csdn.net/weixin_39778570/article/details/83691978

Boxes in a Line
ACM汇总学习:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目:https://vjudge.net/problem/UVA-12657
题目:模拟链表4中操作,x左插入y,x右插入y,x交换y,翻转链表,计算链表中奇数位置的和
解法:使用两个数组模拟双向链表,翻转操作不用真的翻转,记录翻转次数就好,奇数次则反向计算,注意!当链表被翻转过了的时候,x左插入y变为x右插入y,x右插入y边成x左插入y

#include<bits/stdc++.h>
#define ll long long 
#define fo(i,j,n) for(register int i=j; i<=n; ++i)

using namespace std;
const int maxn = 1e5+10;
template <class T>inline bool sf(T &ret){
	char c; int sgn;
	if(c=getchar(),c==EOF)return 0;
	while(c!='-'&&(c<'0'||c>'9'))c=getchar();
	sgn=(c=='-')?-1:1;
	ret=(c=='-')?0:(c-'0');
	while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
	ret*=sgn;
	return ret;
}
struct DList{
	int Left[maxn],Right[maxn];
	int head = 0, tail, inv = 0; 
	void init(int n){
	//	memset(Left,0,sizeof(int)*(n+3));
	//	memset(Right,0,sizeof(int)*(n+3));
		inv = 0;
		head = 0;
		tail = n+1;
		Right[head] = 1;
		fo(i,1,n){
			Left[i] = i-1;
			Right[i] = i+1;
		}
		Left[tail] = n;
//		fo(i,1,n+1)cout<<Left[i]<<" ";
//		putchar(10);
//		fo(i,1,n+1)cout<<Right[i]<<" ";
	}
	void link(int x, int y){ // x连接y 
		Right[x] = y; Left[y] = x;
	}
	void XLeftY(int x, int y){ // x左插y 
		if(x==Left[y]){
			return;
		}else if(x==Right[y]){
			link(Left[y],x);
			link(y,Right[x]);
			link(x,y);
		}else{
			link(Left[x],Right[x]);
			link(Left[y],x);
			link(x,y);
		}
	}
	void XRightY(int x, int y){ // x右插y 
	    if(Right[x]==y){
			link(Left[x],y);
			link(x,Right[y]);
			link(y,x);
		}else if(x==Right[y]){
			return;
		}else{
			link(Left[x],Right[x]);
			link(x,Right[y]);
			link(y,x);
		}
	}
	void XSwapY(int x, int y){ // 交换位置 
		if(Right[x]==y){
			link(Left[x],y);
			link(x,Right[y]);
			link(y,x);
		}else if(Left[x]==y){
			link(Left[y],x);
			link(y,Right[x]);
			link(x,y);
		}else{
			int Lx = Left[x], Rx = Right[x];
			int Ly = Left[y], Ry = Right[y]; 
			link(Lx,y);link(y,Rx);link(Ly,x);link(x,Ry);
		}
	}
	void Inv(){ // 链表逆转 
		inv ^= 1;
	}
	// odd-sum
	ll sum(){
		ll ans = 0;
		if(inv){
			int cnt = 1;
			for(int i=Left[tail]; i; i=Left[i]){
				if(cnt&1) ans += i;
				cnt^=1;
			}
		}else{
			int cnt = 1;
			for(int i=Right[head]; i!=tail; i=Right[i]){
				if(cnt&1) ans += i;
				cnt^=1;
			}
		}
		return ans;
	}
	void PF(){
		int cnt = 1;
		for(int i=Right[head]; i!=tail; i=Right[i]){
			cout<<i<<" ";
			cnt++;
		}
		putchar(10);
		for(int i=Left[tail]; i; i=Left[i]){
			cout<<i<<" ";
			cnt++;
		}
		putchar(10);
	}
}L;
int n,m;
int main(){
	int kase=0;
	while(scanf("%d%d",&n,&m)==2){
		L.init(n);
		int op,x,y;
		fo(i,1,m){
		//	L.PF(); 
			sf(op);
			if(op==4){
				L.Inv();
				continue;
			}
			sf(x),sf(y);
			if(L.inv&&op!=3)op = 3-op; // 逆转过的插入操作要修改,插在左边即插在原串右边 
			if(op==1){
				L.XLeftY(x,y);
			}else if(op==2){
				L.XRightY(x,y);
			}else if(op==3){
				L.XSwapY(x,y);
			}
		}
		ll ans = L.sum();
		printf("Case %d: %lld\n",++kase,ans);
	}	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_39778570/article/details/83691978