链接: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
输出
复制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 ",ans); 87 } 88 return 0; 89 }