zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:位运算(数学)

    题目传送门(内部题72)


    输入格式

      输入文件$bit.in$
      每个输入文件包含$T$组测试数据。输入文件的第一行为一个整数$T$,表示数据组数。接下来$T$行,每行表示一组测试数据每组测试数据包括三个空格隔开的数字 $ResultAnd,ResultOr,ResultXor$,依次表示对$a&b,a|b,a ext{^}b$的限制。
      如果三项中某一项的数字为$-1$,那么说明对这一项没有限制。否则这一项的数字一定是一个非负整数,表示$a$和$b$进行这种运算后的结果。


    输出格式

      输入文件$bit.out$
      $T$行,每行一个整数或一个字符串$"inf"$(不输出引号)。
      第$i$行的整数或字符串表示第$i$组测试数据的答案。


    样例

    样例输入:

    10
    20 1015 995
    921 661 -1
    -1 375 -1
    30445634 30446311 30446245
    11997588 11998143 555
    -1 65535 -1
    -1 465530605 312684161
    2118209 930739953 928621744
    69739040 402620388 332881348
    4594346 533159678 528565332

    样例输出:

    128
    0
    2187
    0
    32
    43046721
    4096
    32768
    131072
    4096


    数据范围与提示

    样例解释:

    样例中$T=10$,且样例的第$i$行是来自第$(2*i-1)$个测试点的一组输入数据

    数据范围:

    对全部测试点:$Tleqslant 10,ResultAnd,ResultOr,ResultXor$都是$[-1,10^9]$区间内的整数。对同一组数据,$ResultAnd,ResultOr,ResultXor$不会均为$-1$。
    第$1$到$5$个测试点:$0leqslant ResultOr leqslant 1023$
    第$6$到$10$个测试点:$ResultOr-ResultAndleqslant 1000,ResultOr>=0,ResultAnd>=0$
    第$11$到$16$个测试点:答案中不会出现$inf$
    第$11$和$12$个测试点还满足:$ResultAnd=ResultXor=-1$
    第$17,18$个测试点满足:不等于$inf$的答案不会超过$int$数据类型能表示的范围
    第$19,20$个测试点:无特殊限制


    题解

    大力分类讨论即可。

    位运算一定要先将其每位提取处理。

    不妨设$a[i],b[i].c[i]$分别表示$&,|, ext{^}$的每一位。

    依次枚举:

      $alpha.$都有限制:$ans=2^{sum limits_{i=1}^{30}a[i] ext{^}b[i]}$。

      $eta.&$没有限制:$ans=2^{sum limits_{i=1}^{30}b[i]&c[i]}$。

      $gamma.|$没有限制:$ans=2^{sum limits_{i=1}^{30}c[i]}$。

      $delta. ext{^}$没有限制:$ans=2^{sum limits_{i=1}^{30}a[i] ext{^}b[i]}$。

      $epsilon.$只有$&$有限制:$ans=inf$。

      $zeta.$只有$|$有限制:$ans=3^{sum limits_{i=1}^{30}b[i]}$。

      $eta.$只有$ ext{^}$有限制:$ans=inf$。

    时间复杂度:$Theta(30 imes T)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int AND,OR,XOR;
    int a[50],b[50],c[50];
    long long qpow(long long x,long long y)
    {
    	long long res=1;
    	while(y)
    	{	
    		if(y&1)res=res*x;
    		x=x*x;
    		y>>=1;
    	}
    	return res;
    }
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		int sum=0;
    		scanf("%d%d%d",&AND,&OR,&XOR);
    		if(AND!=-1&&OR==-1&&XOR==-1){puts("inf");continue;}
    		if(AND==-1&&OR==-1&&XOR!=-1){puts("inf");continue;}
    		if(AND!=-1&&OR!=-1&&XOR!=-1)
    		{
    			for(int i=0;i<=30;i++)
    			{
    				a[i]=(AND>>i)&1;
    				b[i]=(OR>>i)&1;
    				c[i]=(XOR>>i)&1;
    				if(a[i]&&!b[i]){puts("0");goto nxt;}
    				if(a[i]&&c[i]){puts("0");goto nxt;}
    				if(!b[i]&&c[i]){puts("0");goto nxt;}
    				sum+=a[i]^b[i];
    			}
    			printf("%lld
    ",qpow(2,sum));
    		}
    		if(AND!=-1&&OR==-1&&XOR!=-1)
    		{
    			for(int i=0;i<=30;i++)
    			{
    				a[i]=(AND>>i)&1;
    				c[i]=(XOR>>i)&1;
    				if(a[i]&&c[i]){puts("0");goto nxt;}
    				sum+=c[i];
    			}
    			printf("%lld
    ",qpow(2,sum));
    		}
    		if(AND==-1&&OR!=-1&&XOR!=-1)
    		{
    			for(int i=0;i<=30;i++)
    			{
    				b[i]=(OR>>i)&1;
    				c[i]=(XOR>>i)&1;
    				if(!b[i]&&c[i]){puts("0");goto nxt;}
    				sum+=b[i]&c[i];
    			}
    			printf("%lld
    ",qpow(2,sum));
    		}
    		if(AND!=-1&&OR!=-1&&XOR==-1)
    		{
    			for(int i=0;i<=30;i++)
    			{
    				a[i]=(AND>>i)&1;
    				b[i]=(OR>>i)&1;
    				sum+=a[i]^b[i];
    				if(a[i]&&!b[i]){puts("0");goto nxt;}
    			}
    			printf("%lld
    ",qpow(2,sum));
    		}
    		if(AND==-1&&OR!=-1&&XOR==-1)
    		{
    			for(int i=0;i<=30;i++)
    				sum+=(OR>>i)&1;
    			printf("%lld
    ",qpow(3,sum));
    		}
    		nxt:;
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    touch:创建文件及修改文件时间戳
    stat:查看文件时间参数
    获取二维数组里面实际存有数据的行数
    Math.Atan2 方法
    c#移位运算符("<<"及">>")
    c# 一维数组和二维数组的几种定义方式<转>
    C#异常处理总结
    C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)
    WinForm窗体及其控件的自适应
    C#的WinForm窗体美化
  • 原文地址:https://www.cnblogs.com/wzc521/p/11695181.html
Copyright © 2011-2022 走看看