• 洛谷 P5614题解


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

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


    Subtask 1:

    Method:

    直接输出4,完。


    Subtask 2:

    Method:

    直接暴力枚举 (x) , (y) , (z) ,判断是否满足一下关系即可:

    [forall iinleft[1,n ight],s.t.left |a_i-x ight|igoplus left|b_i-y ight| igoplus left|c_i -z ight|=9 ]

    时间复杂度:(O(nM^3))(nleq 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
    ",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 **:

    考虑优化枚举。若满足一下的性质:

    [Aigoplus Bigoplus C=D ]

    则显然可以得到:

    [egin{equation} egin{aligned} & Aigoplus B igoplus D\ & =A igoplus B igoplus left(Aigoplus Bigoplus C ight) \ & = left[left(A igoplus B ight) igoplus left(Aigoplus B ight) ight]igoplus C\ & ecause x igoplus x=0,0igoplus x=x\ & herefore A igoplus B igoplus D =C end{aligned} end{equation} ]

    故只需要枚举 (x)(y) ,则:

    [egin{equation} egin{aligned} & left|c_1-z ight|=left|a_1-x ight|igoplus left|b_1-y ight| igoplus 9 end{aligned} end{equation} ]

    我们设

    [C=left|a_1-x ight|igoplus left|b_1-y ight| igoplus 9 ]

    则:

    [z_1=c_1-C,z_2=c_1+C ]

    最后只需要判断一下 (z_1)(z_2) 是否满足以下性质即可:

    [forall iin left[2,n ight],s.t.left |a_i-x ight|igoplus left|b_i-y ight| igoplus left|c_i -z_j ight|=9 ext{且}z_j in [1,M]\ (jin {1,2}) ]

    时间复杂度:(O(nM^2))(nleq 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
    ",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
    ",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;
    	}
    }
    
  • 相关阅读:
    linux重新编译内核
    无废话ubuntu 13.4w文件共享配置
    VB6关于判断模态窗体的问题
    在.NET中快速创建一个5GB、10GB或更大的空文件
    利用虚拟光驱实现 将WINDOWS文件供虚拟机中的UBUNTU共享
    论这场云盘大战,以及各网盘的优劣
    struts2 全局格式化,格式化时间,金钱,数字
    SQL SERVER 2000/2005/2008数据库数据迁移到Oracle 10G细述
    女攻城师走在移动互联网道路的这两年
    用正则匹配多行文本
  • 原文地址:https://www.cnblogs.com/nth-element/p/11788448.html
Copyright © 2020-2023  润新知