刚开始一列一列考虑,最后再减去能去掉几列,后来才发现是错误的。单独考虑某一列,同时去掉几列时,单独考虑的不一定成立。后来一查是算法竞赛入门经典里面的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;
}