1. 程式人生 > >埃森哲杯第十六屆上海大學程序設計聯賽春季賽暨上海高校金馬五校賽 C序列變換

埃森哲杯第十六屆上海大學程序設計聯賽春季賽暨上海高校金馬五校賽 C序列變換

整數 sub target OS Go space != while opened

鏈接:https://www.nowcoder.com/acm/contest/91/C
來源:牛客網
沒有賬號的同學這樣註冊,支持博主

技術分享圖片

題目描述

給定兩個長度為n的序列,ai, bi(1<=i<=n), 通過3種魔法使得序列a變換為序列b,也就是ai=bi(1<=i<=n).

魔法1: 交換ai和aj,i!=j

首先通過若幹次的魔法1將序列a變換成序列c

魔法2: 對1個數乘2或者加1

魔法3: 對1個數除以2或者減1,如果是奇數,則不能除以2

若ci>bi, 則只能對ci實施魔法3,若ci<bi, 則只能對ci實施魔法2. 例如ci=6, bi=4,

則可以通過對ci實施2次減1操作(魔法3)將ci變為bi, 但不可以對ci除以2再加1將ci變為bi,因為ci>bi, 所以不能對ci實施加1操作(魔法2).

小埃想通過最少的操作次數使得序列a變成序列b, 操作次數是指使用的魔法次數。

輸入描述:

輸入測試組數T,每組數據,第一行輸入n,1<=n<=9,緊接著輸入兩行,每行n個整數,前一行為a1,a2,…,an,後一行為b1,b2,…,bn.其中1<=ai,bi<=108,1<=i<=n.

輸出描述:

每組數據輸出一個整數,表示最少的操作次數
示例1

輸入

復制
2
2
8 7
5 1
4
4 3 1 3
1 1 4 3

輸出

復制
6
3



分析題目,三種操作中,2和3是一樣的,1就是交換。
由於N很小很小,可以枚舉每種交換的情況。枚舉方式:全排列,循環一遍統計生成當前排列所需的交換數。

問題就在於如何求出a[i]通過2或3操作變成b[j]的方案數。
從較大的數向較小的數推,貪心即可求!!!!!具體見代碼的calc函數。
這部分需要預處理,如果不預處理的話復雜度加一個log就過不了了。

技術分享圖片
 1 /*
 2 ◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
 3 ◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇
 4 ◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇
5 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇ 6 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◇◆◆◆◇◇◇◇◇ 7 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◆◆◆◆◆◇◇◇◇◇ 8 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◆◆◇◇◇◇◇◇◇◇◇◇◆◆◇◆◆◇◇◇◇◇ 9 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◆◇◇◇◆◇◇◇◇◇ 10 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◇◆◆◇◇◇◇◇◇◇◇◇◇◇◇◆◇◇◇◆◇◇◇◇◇ 11 ◇◇◇◇◇◇◇◆◇◇◇◇◇◇◇◇◇◇◇◇◆◆◆◇◆◇◇◇◇◇◇◇◇◇◇◆◇◇◇◆◇◇◇◇◇ 12 ◇◇◇◇◇◇◆◆◆◆◇◇◇◇◇◇◇◇◇◇◆◆◆◆◆◇◇◇◇◇◇◇◇◇◆◆◆◇◆◆◆◇◇◇◇ 13 ◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇ 14 ◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇ 15 ◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇ 16 ◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇ 17 */ 18 #include<iostream> 19 #include<cstdio> 20 #include<cstring> 21 #include<ctime> 22 #include<cstdlib> 23 #include<algorithm> 24 #include<cmath> 25 #include<string> 26 using namespace std; 27 int read(){ 28 int xx=0,ff=1;char ch=getchar(); 29 while(ch>9||ch<0){if(ch==-)ff=-1;ch=getchar();} 30 while(ch>=0&&ch<=9){xx=xx*10+ch-0;ch=getchar();} 31 return xx*ff; 32 } 33 int N,a[10],b[10],c[10],t[10],lin[10],cost[10][10]; 34 int calc(int x,int y){ 35 if(x<y) 36 swap(x,y); 37 int re=0; 38 while(x!=y){ 39 if(x%2==0){ 40 if(x/2>=y) 41 x/=2,re++; 42 else 43 re+=x-y,x=y; 44 } 45 else 46 x--,re++; 47 } 48 return re; 49 } 50 int main(){ 51 //freopen("in.txt","r",stdin); 52 for(int T=read();T;T--){ 53 N=read(); 54 for(int i=1;i<=N;i++) 55 a[i]=read(); 56 for(int i=1;i<=N;i++) 57 b[i]=read(); 58 for(int i=1;i<=N;i++) 59 c[i]=i; 60 for(int i=1;i<=N;i++) 61 for(int j=1;j<=N;j++) 62 cost[i][j]=calc(a[i],b[j]); 63 /*for(int i=1;i<=N;i++){ 64 for(int j=1;j<=N;j++) 65 printf("%d ",cost[i][j]); 66 puts(""); 67 }*/ 68 int ans=(1LL<<31)-1,now; 69 do{ 70 now=0; 71 for(int i=1;i<=N;i++) 72 t[i]=c[i],lin[t[i]]=i; 73 for(int i=1;i<=N;i++) 74 if(t[i]!=i){ 75 int j=lin[i]; 76 swap(t[i],t[j]); 77 lin[t[i]]=i; 78 lin[t[j]]=j; 79 now++; 80 } 81 for(int i=1;i<=N;i++) 82 now+=cost[c[i]][i]; 83 if(now<ans) 84 ans=now; 85 }while(next_permutation(c+1,c+1+N)); 86 printf("%d\n",ans); 87 } 88 return 0; 89 }
View Code








埃森哲杯第十六屆上海大學程序設計聯賽春季賽暨上海高校金馬五校賽 C序列變換