6741870 | 60 | 1002 |
題目大意如下:給定n個LED燈串,每個燈串由p個LED燈構成,並給出每個燈串當下的狀態,需要讓所有燈串中規定的某些燈滅掉,詢問最少剩下幾盞正常的燈可以讓我們分辨出LED燈原先代表的數字。
思路如下:正難則反。既然不可能一個個判斷燈串所代表的符號,那麼就只需判斷若滅掉一些燈之後,n個燈串中剩下的亮燈是否有兩組相同,若有,則分辨不出。因爲滅掉的燈的種類和數量不定。那麼,問題就可以轉化爲,用子集生成算法枚舉剩下的燈串或滅掉的燈串,再判斷是否出現了非法燈串就行了。而這裏我用的是增量法枚舉剩下的亮燈。
代碼如下:(2KB)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int a[20],p,n,ans;
bool pdt[110][20];
bool same(int x,int y,int cur)
{
for(int i=0;i<cur;i++)
if(pdt[x][a[i]]^pdt[y][a[i]])
return 0;
return 1;
}
bool jud(int cur)
{
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
if(same(i,j,cur))return 0;
return 1;
}
void sub(int cur)
{
if(jud(cur))
ans=min(ans,cur);
int s=cur?a[cur-1]+1:0;
for(int i=s;i<p;i++){
a[cur]=i;
sub(cur+1);
}
}
void Init()
{
ans=0x3f3f3f3f;
scanf("%d%d",&p,&n);
for(int i=0;i<n;i++)
for(int j=0;j<p;j++)
scanf("%d",&pdt[i][j]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
Init();
sub(0);
printf("%d\n",ans);
}
return 0;
}