Boxes in a Line UVA
阿新 • • 發佈:2018-12-11
題目:
對一行陣列有四種操作:
1.把數字x放到數字y的左邊
2.把數子X放到數字Y的右邊
3.交換X和Y的位置
4.把所有數字翻轉順序
思路:
如果用陣列的話,明顯第四個操作就會明顯超時。所以採用連結串列。用連結串列模擬一下就行。此處採用陣列模擬連結串列實現
對於第四種操作,可以用一個變數去判斷是否翻轉,如果翻轉的話,只需要把原來的左右指標交換即可。
注意交換的時候,兩個數字相鄰和兩個數字不相鄰是兩種不同的方式。
程式碼:
/*by kzl*/ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> using namespace std; const int maxx = 1e5+500; const int INF = 0x3f3f3f3f; typedef long long LL; int n,m,a,x,y; int lnext[maxx],rnext[maxx]; long long sum = 0; void init() { for(int i=1; i<=n; i++)rnext[i] = i+1,lnext[i] = i-1; rnext[0] = 1;lnext[0] = n;rnext[n] = 0; sum = 0; } void one(int l[],int r[],int x,int y){ if(l[y]==x)return; l[r[x]] = l[x]; //把X從列表中刪除 r[l[x]] = r[x]; r[l[y]] = x;//將x插入到y左側 l[x] = l[y]; r[x] = y; l[y] = x; } void two(int l[],int r[],int x,int y){ if(r[y]==x)return; l[r[x]] = l[x]; //把X從列表中刪除 r[l[x]] = r[x]; //將x插入到y右側 l[r[y]] = x; r[x] = r[y]; r[y] = x; l[x] = y; } void three(int l[],int r[],int x,int y){ if(r[y]==x)swap(x,y); if(r[x]==y){ r[x] = r[y]; l[r[y]] = x; l[y] = l[x]; r[l[x]] = y; r[y] = x; l[x] = y; return ; } int cc = r[x],dd = l[x]; l[r[y]] = x;r[l[y]] = x; r[x] = r[y];l[x] = l[y]; l[cc] = y;r[dd] = y; r[y] = cc;l[y] = dd; } void getsum(int ne[]){ for(int i = ne[0],j=1;i!=0;i = ne[i],j++){ if(j&1&&i<=n)sum+=i; } } int main() { int num = 1; while(scanf("%d%d",&n,&m)!=EOF) { init(); int flag = 0; for(int i=0; i<m; i++) { scanf("%d",&a); if(a==1) //move box X to the left to Y { scanf("%d%d",&x,&y); if(flag==0) { one(lnext,rnext,x,y); } else one(rnext,lnext,x,y); } else if(a==2) { scanf("%d%d",&x,&y); if(flag==0) { two(lnext,rnext,x,y); } else two(rnext,lnext,x,y); } else if(a==3) { scanf("%d%d",&x,&y); if(flag==0) { three(lnext,rnext,x,y); } else three(rnext,lnext,x,y); } else if(a==4) { flag = flag^1; } } if(flag==0)getsum(rnext); else getsum(lnext); printf("Case %d: %lld\n",num++,sum); } return 0; }
可優化:
以上程式碼可以有以下優化:
1.連線兩個節點的操作可以寫成一個函式,節省程式碼。
2.對於4操作,因為因為他隻影響了1,2的順序,而且1,2操作相對來說正好關於4操作對稱,所以翻轉之後的1操作實際就是之前的2操作。而不必要翻轉指標。