首页 > 代码库 > The Broken Pedometer UVA 11205

The Broken Pedometer UVA 11205

说说:

       这题开始的时候理解有错误,以为只要对每个位进行判断,即如果每个数的该位都不考虑,若出现两个数字完全相同,则该位是必须存在的,否则即是可有可无的。但是这么做其实是有问题的,因为这就默认对于某位的判断是基于其他位都是有效的情况。而事实上应当在将无效位全都去除之后,再对需要判断的位进行判断才是合理的,但这明显不能满足。因此在网上也看了一些其他人的解题报告,最简单的应该就是用位向量的方法了。即把P位数的每个位是否有效进行排列组合,列出所有情况进行判断,进行暴力求解即可。


源代码:

#include <stdio.h>
#include <string.h>
#define MAXP 15+5
#define MAXN 100+5

int s[MAXN][MAXP];
char cpy[MAXN][MAXP];
char valid[MAXP];
int N,P,ans;

void solve(int cur){
  int i,j,count;
  if(cur==P){
    count=0;//记录有效位的个数
    for(i=0;i<P;i++)
      if(valid[i]){//有效位根据获取的数据填入
        count++;
        for(j=0;j<N;j++)
	  cpy[j][i]='0'+s[j][i];
	}
      else
        for(j=0;j<N;j++)//无效位直接置零
	  cpy[j][i]='0';
    
    for(i=0;i<N;i++) cpy[i][P]='\0';//不要忘记最后放置字符串结束标识
    
    for(i=0;i<N;i++)
      for(j=i+1;j<N;j++)
        if(strcmp(cpy[i],cpy[j])==0)//若发现有重复,说明此种排序不行
	  return;
    
    if(count<ans) ans=count;
    return;
  }

 valid[cur]=0;//位向量法,列出所有情况
 solve(cur+1);
 valid[cur]=1;
 solve(cur+1);

 return;
}

int main(){
  int i,j,k,T;
 // freopen("data","r",stdin);
  scanf("%d",&T);

  while(T--){
    scanf("%d%d",&P,&N);

    for(i=0;i<N;i++)
      for(j=0;j<P;j++)
        scanf("%d",&s[i][j]);

    ans=P;
    solve(0);

    printf("%d\n",ans);
  }

  return 0;
}

The Broken Pedometer UVA 11205