求下列方法的证明和 Hack
查看原帖
求下列方法的证明和 Hack
430133
liangbob楼主2024/12/2 20:54

似乎跟 365751 的方法差不多?

对于 s1s_1s2s_2 各开一个并查集,如果相邻两个数可交换,那么合并它们。分别统计两个并查集内所含 0/10/1 的个数

然后对于所有 1in1\le i \le n,如果 ii 所在的交换块内能“调出”相同的数,那么答案加一。

能通过民间数据,但感觉很假,希望有大佬能给出简要的证明或者 Hack。

void solve()
{
    cin >> n;
    cin >> (s1 + 1) >> (s2 + 1) >> (t1 + 1) >> (t2 + 1);
    for(int i = 1;i <= n;i++)
    {
        c0[i] = c1[i] = d0[i] = d1[i] = 0;
        fa1[i] = fa2[i] = i;
    }
    for(int i = 2;i <= n;i++)
    {
        if(t1[i] == '1' && t1[i - 1] == '1') fa1[i] = fa1[i - 1];
        if(t2[i] == '1' && t2[i - 1] == '1') fa2[i] = fa2[i - 1];
    }
    for(int i = 1;i <= n;i++)
    {
        if(s1[i] == '0') c0[fa1[i]]++;
        else if(s1[i] == '1') c1[fa1[i]]++;
        if(s2[i] == '0') d0[fa2[i]]++;
        else if(s2[i] == '1') d1[fa2[i]]++;
    }
    int ans = 0;
    for(int i = 1;i <= n;i++)
    {
        int fx = fa1[i], fy = fa2[i];
        if(d0[fy] && c0[fx]) 
        {
            ans++;
            d0[fy]--;
            c0[fx]--;
        }
        else if(d1[fy] && c1[fx])
        {
            ans++;
            d1[fy]--;
            c1[fx]--;
        }
    }
    cout << ans << endl;
}
2024/12/2 20:54
加载中...