内容来自《挑战程序设计竞赛》
以下为原书代码, 我假设你已经看懂作者对本题解法的描述,以及书中使用的方法,我只说一说我对代码的一些难点的理解,关于if中的语句能否充分排除矛盾的讨论。
int N,K;
int T[MAX_K],X[MAX_K],Y[MAX_K];
void solve()
{
init(N*3);
int ans=0;
for(int i=0;i>K;i++)
{
int t=T[i];
int x=X[i]-1,y=Y[i]-1; //把范围变为0到N-1
if(x<0||N<=x||y<0||N<=y)
{
ans++;
continue;
}
if(t==1)
{
if(same(x,y+N)||same(x,y+2*N)) //***这是我要重点说的
ans++;
else
{
unite(x,y);
unite(x+N,y+N);
unite(x+2*N,y+2*N);
}
}
else
{
if(same(x,y)||same(x,y+2*N)) //***这是我要重点说的
ans++;
else{
unite(x,y+N);
unite(x+N,y+2*N);
unite(x+2*N,y);
}
}
}
printf("%d/n",ans);
}
请在看懂以上题意,解法讲解,代码的情况下对if中的条件有疑问的情况下再看一下解释,否则可以直接退出了。
为什么if(same(x,y+N)||same(x,y+2*N)) 这个条件足够充要来排除错误情况呢?
我们要判断x,y是否是同一类型,也就是说从反面判断x是否吃y(情况same(x,y+N)),以及y是否吃x(情况same(x,y+2*N))。如果在前面的判断中出现以上任意情况,肯定能确定x,y不是同一类,if能充分地判断。(要是不理解的话建议回头看看x吃y,或y吃x要是正确的话是怎么unite的)。
为什么 if(same(x,y)||same(x,y+2*N))这个条件足够充要来排除错误情况呢?
我们要判断x是否吃y(单向吃),反方向思考,只要x,y不相等(same(x,y+N))并且y不吃x(same(x,y+2*N)),那么剩下的可能只能是x吃y。所以if的条件也是充分的