首先发现:一个数最多会出现1次;
然后深入推出:一个数不会既用它又用它的相反数;
这样就可以依次考虑每一位了:
如果所有的数都不含有这一位,那么就直接把所有的数除以2
如果含有,那么就减去这一位的数,再除以2;
2
当含有的时候搜索就可以了;
注意需通过去重来优化dfs,否则会TLE掉;
#include <bits/stdc++.h> #define N 100010 using namespace std; int a[N],b[21][N],ans[N],st[N],top=0; int anss=INT_MAX; void dfs(int dep,int n){ if(n<=1&&!b[dep][1]){ if(top<anss){ anss=top; for(int i=1;i<=top;i++){ ans[i]=st[i]; } } return; } if(dep>20||top>=anss){ return; } bool flag=1; for(int i=1;i<=n;i++){ if(b[dep][i]&1){ flag=0; break; } } if(flag){ for(register int i=1;i<=n;i++){ b[dep+1][i]=b[dep][i]/2; } n=unique(b[dep+1]+1,b[dep+1]+n+1)-b[dep+1]-1; dfs(dep+1,n); return; } else{ for(register int i=1;i<=n;i++){ if(b[dep][i]&1){ b[dep+1][i]=(b[dep][i]-1)/2; } else{ b[dep+1][i]=b[dep][i]/2; } } st[++top]=1*(1<<dep); register int tmp=unique(b[dep+1]+1,b[dep+1]+n+1)-b[dep+1]-1; dfs(dep+1,tmp); top--; for(register int i=1;i<=n;i++){ if(b[dep][i]&1){ b[dep+1][i]=(b[dep][i]+1)/2; } else{ b[dep+1][i]=b[dep][i]/2; } } st[++top]=-1*(1<<dep); tmp=unique(b[dep+1]+1,b[dep+1]+n+1)-b[dep+1]-1; dfs(dep+1,tmp); top--; } } int main() { register int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+n+1); n=unique(a+1,a+n+1)-a-1; for(int i=1;i<=n;i++){ b[0][i]=a[i]; } dfs(0,n); printf("%d\n",anss); for(int i=1;i<=anss;i++){ printf("%d ",ans[i]); } }