题目
思路
不得不说这题还是有坑的,其实每一次称量都可以抽象为一个m元1次且最大系数为1的方程,接下来我们枚举
n
+
1
n+1
n+1种情况,枚举到i时,考虑当第i种情况成立且唯一(即没有别的称量错误的方法有合法答案)的解。
code:
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
int n,w,k;
struct f{
double a[111];
int id;
} a[111],b[111];
double x,y;
bool f(int u)
{
for (int i=0,j=0;i<=n;i++,j++)
{
if (i==u)
{
j--;
continue;
}
a[j]=b[i];
}
for (int j=0;j<n;j++)
{
int t=j;
while (a[t].a[j]==0&&t<n) t++;
if (t==n)
{
return 0;
}
swap(a[t],a[j]);
for (int i=0;i<n;i++)
{
if (i==j) continue;
x=a[i].a[j]/a[j].a[j];
for (int k=0;k<=n;k++) a[i].a[k]-=a[j].a[k]*x;
}
}
double mx=-1;
int kk;
for (int j=0;j<n;j++)
{
if (a[j].a[n]/a[j].a[j]!=(int)(a[j].a[n]/a[j].a[j])) return 0;
if (a[j].a[n]/a[j].a[j]<1) return 0;
if (mx<a[j].a[n]/a[j].a[j])
{
mx=a[j].a[n]/a[j].a[j];
kk=j;
}
}
for (int j=0;j<n;j++)
{
if (kk!=j&&mx==a[j].a[n]/a[j].a[j]) return 0;
}
k=kk;
return 1;
}
int main()
{
cin>>n;
for (int i=0;i<=n;i++)
{
b[i].id=i;
int m;
cin>>m;
for (int j=1;j<=m;j++)
{
int x;
cin>>x;
b[i].a[x-1]=1;
}
cin>>b[i].a[n];
}
for (int i=0;i<=n;i++)
{
if (f(i)) w++;
}
if (w!=1)
{
cout<<"illegal";
return 0;
}
cout<<k+1;
return 0;
}