看了并查集神做法,发现后面还是暴力。。
先用并查集将各个相等的砝码连在一起作为一个整体。
然后根据当前条件求出可以求出的值,不能求出具体值的求出可能是1-2还是2-3。
然后就是最重要的,枚举i,j再枚举a,b,i,j可能的值。
因为题目要将只有唯一的选法加入,所以如果4个砝码出现同时存在>,<,=其中大于两种情况,就不选。
建议可以去看看fuxey的
#include <cstdio>
#include <vector>
using namespace std;
const int N=55;
vector<int> que;
int n,a,b,fa[N],ans1,ans2,ans3;
char ch[N][N];
int vl[6],kl[6];
int g[N][N],val[N],l[N],r[N];
int getf(int x)
{
return fa[x]==x?x:(fa[x]=getf(fa[x]));
}
inline void link(int x,int y)
{
int fx=getf(x),fy=getf(y);
if(fx==fy) return;
fa[fx]=fy;
return ;
}
inline int pd(int x)
{
if (x==0) return 0;
if (x>0) return 1;
return -1;
}
int main()
{
register int i,j;//,k,v;
scanf("%d %d %d",&n,&a,&b);
for (i=1;i<=n;i++)
{
scanf("%s",ch[i]);
fa[i]=i;
}
for (i=n;i>=1;i--)
{
for (j=n;j>=1;j--)
{
ch[i][j]=ch[i][j-1];
}
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
if (ch[i][j]=='=') link(i,j);
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
if (ch[i][j]=='+') g[getf(i)][getf(j)]=1,g[getf(j)][getf(i)]=-1;
if (ch[i][j]=='-') g[getf(i)][getf(j)]=-1,g[getf(j)][getf(i)]=1;
}
for (i=1;i<=n;i++) if (getf(i)==i) que.push_back(i);
for (i=0;i<que.size();i++)
{
int big=0,small=0;
for (j=0;j<que.size();j++)
big|=(g[que[i]][que[j]]==1),small|=(g[que[i]][que[j]]==-1);
if (!big||!small) continue;
val[que[i]]=2;
for (j=0;j<que.size();j++)
{
if (g[que[i]][que[j]]) val[que[j]]=2-g[que[i]][que[j]];
}
}
int x;
for (i=0;i<que.size();i++)
{
x=que[i];
l[x]=1;r[x]=3;
if (val[x]) l[x]=r[x]=val[x];
else
{
for (j=0;j<que.size();j++)
{
if(g[x][que[j]]==1) l[x]=2;
else if(g[x][que[j]]==-1) r[x]=2;
}
}
}
bool fl;
int p1=0,p2=0,p3=0;
kl[1]=a;kl[2]=b;
for (i=1;i<=n;i++)
{
if (i!=a&&i!=b)
for (j=i+1;j<=n;j++)
if (j!=a&&j!=b)
{
p1=p2=p3=0;
for (vl[1]=l[fa[a]];vl[1]<=r[fa[a]];vl[1]++)
for (vl[2]=l[fa[b]];vl[2]<=r[fa[b]];vl[2]++)
for (vl[3]=l[fa[i]];vl[3]<=r[fa[i]];vl[3]++)
for (vl[4]=l[fa[j]];vl[4]<=r[fa[j]];vl[4]++)
{
kl[3]=i;kl[4]=j;
fl=true;
for (int k=1;k<=4;k++)
for (int v=k+1;v<=4;v++)
{
if (fa[kl[k]]==fa[kl[v]]&&vl[k]!=vl[v]) {fl=false;k=5;break;}
else if (g[fa[kl[k]]][fa[kl[v]]]&&g[fa[kl[k]]][fa[kl[v]]]!=pd(vl[k]-vl[v])) {fl=false;k=5;break;}
}
if (!fl) continue;
if(vl[1]+vl[2]==vl[3]+vl[4])
{
p2=1;
}
if(vl[1]+vl[2]<vl[3]+vl[4])
{
p3=1;
}
if(vl[1]+vl[2]>vl[3]+vl[4])
{
p1=1;
}
}
if (p1+p2+p3==1) ans1+=p1,ans2+=p2,ans3+=p3;
}
}
printf("%d %d %d\n",ans1,ans2,ans3);
return 0;
}