洛谷 P5614题解

吐槽:数据好像有点水,直接枚举到200可以得80 points。

另:我还是太弱了,比赛的时候只有90 points,#7死卡不过去,最后发现是没有判断 \(z_1\) 和 \(z_2\) 的范围……


Subtask 1:

Method:

直接输出4,完。


Subtask 2:

Method:

直接暴力枚举 \(x\) , \(y\) , \(z\) ,判断是否满足一下关系即可:
\[ \forall i\in\left[1,n\right],s.t.\left |a_i-x\right|\bigoplus \left|b_i-y\right| \bigoplus \left|c_i -z\right|=9 \]
时间复杂度:\(O(nM^3)\) ( \(n\leq 5\) ,可以忽略 )

可以通过 \(60\%\) 的数据。

Code

#include<bits/stdc++.h>
#define int long long 
#define Maxn 10
using namespace std;
inline void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,M;
int ans=0;
int a[Maxn],b[Maxn],c[Maxn];
void solve1()
{
    int flag=1;
    for(int x=1;x<=M;x++)
    {
        for(int y=1;y<=M;y++)
        {
            for(int z=1;z<=M;z++)
            {
                for(int i=1;i<=n;i++)
                {
                    if((((abs(a[i]-x))^(abs(b[i]-y)))^(abs(c[i]-z)))!=9)
                    {
                        flag=0;
                        break;
                    }
                }
                if(flag==1)
                {
                    ans++;
                }else
                {
                    flag=1;
                }
            } 
        }
    }
    printf("%lld\n",ans);
    return ;    
} 
signed main()
{
    read(n),read(M);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        read(b[i]);
        read(c[i]);
    }
    ans=0;
    if(M<=200)
    {
        solve1();
        return 0;
    }
}

Subtask 3:

Method :

考虑优化枚举。若满足一下的性质:
\[ A\bigoplus B\bigoplus C=D \]
则显然可以得到:
\[ \begin{equation} \begin{aligned} & A\bigoplus B \bigoplus D\\ & =A \bigoplus B \bigoplus \left(A\bigoplus B\bigoplus C\right) \\ & = \left[\left(A \bigoplus B\right) \bigoplus \left(A\bigoplus B\right)\right]\bigoplus C\\ & \because x \bigoplus x=0,0\bigoplus x=x\\ & \therefore A \bigoplus B \bigoplus D =C \end{aligned} \end{equation} \]
故只需要枚举 \(x\) 、\(y\) ,则:
\[ \begin{equation} \begin{aligned} & \left|c_1-z\right|=\left|a_1-x\right|\bigoplus \left|b_1-y\right| \bigoplus 9 \end{aligned} \end{equation} \]
我们设
\[ C=\left|a_1-x\right|\bigoplus \left|b_1-y\right| \bigoplus 9 \]
则:
\[ z_1=c_1-C,z_2=c_1+C \]
最后只需要判断一下 \(z_1\) 和 \(z_2\) 是否满足以下性质即可:
\[ \forall i\in \left[2,n\right],s.t.\left |a_i-x\right|\bigoplus \left|b_i-y\right| \bigoplus \left|c_i -z_j\right|=9\text{且}z_j \in [1,M]\\ (j\in \{1,2\}) \]
时间复杂度:\(O(nM^2)\) ( \(n\leq 5\) ,可以忽略 )

Code:

#include<bits/stdc++.h>
#define int long long 
#define Maxn 10
using namespace std;
inline void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,M;
int ans=0;
int a[Maxn],b[Maxn],c[Maxn];
map<int,int>mp;
void solve1()
{
    int flag=1;
    for(int x=1;x<=M;x++)
    {
        for(int y=1;y<=M;y++)
        {
            for(int z=1;z<=M;z++)
            {
                for(int i=1;i<=n;i++)
                {
                    if((((abs(a[i]-x))^(abs(b[i]-y)))^(abs(c[i]-z)))!=9)
                    {
                        flag=0;
                        break;
                    }
                }
                if(flag==1)
                {
                    ans++;
                }else
                {
                    flag=1;
                }
            } 
        }
    }
    printf("%lld\n",ans);
    return ;    
} 
void solve2()
{
    int flag1=1,flag2=1;
    for(int x=1;x<=M;x++)
    {
        for(int y=1;y<=M;y++)
        {
            mp.clear();
            int tmp=(((abs(a[1]-x))^(abs(b[1]-y)))^9);
            int zkkk=c[1]-tmp;
            int zwww=c[1]+tmp;
            if(zkkk>=1&&zkkk<=M)
            {
                for(int i=2;i<=n;i++)
                {
                    if((((abs(a[i]-x))^(abs(b[i]-y)))^(abs(c[i]-zkkk)))!=9)
                    {
                        flag1=0;
                        break;
                    }
                }
                if(flag1==1&&mp.find(zkkk)==mp.end())
                {
                    ans++;
                    mp[zkkk]=1;
                }else
                {
                    flag1=1;
                }
            }else
            {
                flag1=1;
            }
            if(zwww>=1&&zwww<=M)
            {
                for(int i=2;i<=n;i++)
                {
                    if((((abs(a[i]-x))^(abs(b[i]-y)))^(abs(c[i]-zwww)))!=9)
                    {
                        flag2=0;
                        break;
                    }
                }
                if(flag2==1&&mp.find(zwww)==mp.end())
                {
                    ans++;
                }else
                {
                    flag2=1;
                }
            }else
            {
                flag2=1;
            }
        }   
    }
    printf("%lld\n",ans);
    return ;
}
signed main()
{
    read(n),read(M);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        read(b[i]);
        read(c[i]);
    }
    ans=0;
    if(M<=200)
    {
        solve1();
        return 0;
    }
    else 
    {
        solve2();
        return 0;
    }
}
上一篇:CodeForces 1322B - Present【二进制】


下一篇:[CQOI2013]新Nim游戏