刚开始一列一列考虑,最后再减去能去掉几列,后来才发现是错误的。单独考虑某一列,同时去掉几列时,单独考虑的不一定成立。后来一查是算法竞赛入门经典里面的p188页的位向量法。原来一直以为这边书空有理论,现在想想只是自己找不到如何用,以后还是要好好看着这几本书。还有可以用strcmp来比较字符串,刚开始自己用了建立一个b数组,按二进制的方法计算每一个值,再进行排序来比较,比较麻烦。
#include "stdio.h" #include "string.h" int use[20],a[120][20],n,p,ans; char str[120][20]; void ps(int cur) { //printf("%d\n",ans); int i,j,t; if(cur==p) { //printf("%d\n",ans); t=0; for(i=0; i<p; i++) { if(use[i]) { for(j=0; j<n; j++) str[j][t]='0'+a[j][i]; t++; } } for(i=0; i<n; i++) str[i][t]=0; for(i=0; i<n-1; i++) for(j=1+i ; j<n; j++) if(strcmp(str[i],str[j])==0) return; if(t<ans) ans=t; return; // printf("%d\n",t); } use[cur]=1; ps(cur+1); use[cur]=0; ps(cur+1); } int main() { int cas,i,j; scanf("%d",&cas); while(cas--) { scanf("%d%d",&p,&n); memset(use,0,sizeof(use)); memset(str,0,sizeof(str)); for(i=0; i<n; i++) for(j=0; j<p; j++) scanf("%d",&a[i][j]); ans=p; ps(0); printf("%d\n",ans); } return 0; }
*#include "stdio.h" #include "string.h" #include "algorithm" using namespace std; int a[120][20],p,n,ans,b[120],k,c[120]; bool dfs(int m) { memcpy(b,c,sizeof(b)); int i; for(i=0;i<n;i++) b[i]-=k*a[i][m]; sort(b,b+n); for(i=0;i<n-1;i++) if(b[i]==b[i+1]) return 0; return 1; } int main() { int cas,i,j,t; scanf("%d",&cas); while(cas--) { scanf("%d%d",&p,&n); memset(b,0,sizeof(b)); for(i=0;i<n;i++) { t=1; for(j=0;j<p;j++) { scanf("%d",&a[i][j]); b[i]+=t*a[i][j]; t*=2; //printf("%d\n",b[i]); } } ans=p; //for(i=0;i<n;i++) printf("%d\n",b[i]); memcpy(c,b,sizeof(b)); k=1; for(i=0;i<p;i++) { if(dfs(i)) ans--; k*=2; } //if(ans==0) ans=1; printf("%d\n",ans); } return 0; }