埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换...
生活随笔
收集整理的這篇文章主要介紹了
埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈接: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
?
轉載于:https://www.cnblogs.com/lzhAFO/p/9119575.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 C序列变换...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java集合之TreeMap源码解析上篇
- 下一篇: 独立线性度 最佳直线