标签:
枚举。
看了这个方法:$http://www.cppblog.com/shiming413/archive/2008/12/21/29671.html$
将数字归类的地方不能用$vector$,会超时。$vector$换成数组就可以过,类似于邻接表。
因为题目给出的$16$个数字都是不同的,所以时间复杂度相对还比较低。
下面这组数据是极限数据,我的跑了$3800$$ms$。但测试数据中不会出现这样的数据。
$5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$ $5$
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-6; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } } int a[20],b[20]; LL h[(1<<16)+10]; struct X { int b, nx; }e[50000]; int g[11000],k; void add(int a,int b) { e[k].b=b; e[k].nx=g[a]; g[a]=k++; } int main() { int cas=1; while(~scanf("%d",&a[0])) { if(a[0]==0) break; for(int i=1;i<=15;i++) scanf("%d",&a[i]); k=0; memset(g,-1,sizeof g); for(int i=0;i<(1<<16);i++) { int t=i,cnt=0; for(int j=0;j<16;j++) if(i&(1<<j)) b[cnt++]=j; if(cnt!=4) continue; sort(b,b+4); do { add(4*a[b[0]]+3*a[b[1]]+2*a[b[2]]+1*a[b[3]],i); }while(next_permutation(b,b+4)); } memset(h,0,sizeof h); for(int i=1;i<=10500;i++) { for(int j=g[i];j!=-1;j=e[j].nx) { for(int d=e[j].nx;d!=-1;d=e[d].nx) { int f1=e[d].b,f2=e[j].b; if(f1&f2) continue; h[f1^f2]++; } } } LL ans=0; for(int i=0;i<(1<<16);i++) { int t=i,cnt=0; for(int j=0;j<16;j++) if(i&(1<<j)) cnt++; if(cnt!=8) continue; ans=ans+h[i]*h[(1<<16)-1-i]; } printf("Case %d: %lld\n",cas++,ans/2); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zufezzt/p/5831556.html