传送门:http://codeforces.com/contest/879/problem/C

本题是一个位运算问题——位运算的等价变换。

假设位运算符“&”“|”“^”是左结合的,且优先级相同,则一个表达式:“x@a[1]@a[2]@...@a[n]”,等价于“(...((x@a[1])@a[2])...)@a[n]”。其中,“@”为位运算符“&”“|”“^”。

将表达式“x@a[1]@a[2]@...@a[n]”表示为一个简单的等价形式:“((x&a)|b)^c”,即“x&a|b^c”。

限制条件:“(x>=0)&&(x<=0x3ff)”。

一位数的位运算:

  “&”: 0&0=0,0&1=0,1&0=0,1&1=1;

  “|”: 0|0=0,0|1=1,1|0=1,1|1=1;

  “^”: 0^0=0,0^1=1,1^0=1,1^1=0。

将表达式看成一个映射:“f:x->((x&a)|b)^c”。

此映射服从运算规律:“f(x)=x@a[1]@a[2]@...@a[n]”。

则可枚举x,比较x和f(x)的每一位,据此推测a、b、c。

实际上,由于位运算中的每一位是独立的,因此只需测试两个值:0x0(0b00,0000,0000)和0x3ff(0b11,1111,1111B)。之后比较0和f(0x0)的每一位,以及1和f(0x3ff)的每一位。

记映射f可以分解为若干个位(bit)映射,位i的映射为f[i],则:

  若f[i]:0->0,1->0,则f[i]=“&0,|0,^0”,即a[i]=0,b[i]=0,c[i]=0;

  若f[i]:0->0,1->1,则f[i]=“&1,|0,^0”,即a[i]=1,b[i]=0,c[i]=0;

  若f[i]:0->1,1->0,则f[i]=“&1,|0,^1”,即a[i]=1,b[i]=0,c[i]=1;

  若f[i]:0->1,1->1,则f[i]=“&1,|1,^0”,即a[i]=1,b[i]=1,c[i]=0。

于是,对每一位构造a、b、c的对应位即可。

参考程序如下:

#include <stdio.h>

int main(void)
{
int n;
int x = , y = 0x3ff;
scanf("%d", &n);
for (int i = ; i < n; i++) {
getchar();
char op = getchar();
int num;
scanf("%d", &num);
switch (op) {
case '&':
x &= num;
y &= num;
break;
case '|':
x |= num;
y |= num;
break;
case '^':
x ^= num;
y ^= num;
break;
default:
break;
}
}
int num_and = , num_or = , num_xor = ;
for (int i = ; i < ; i++) {
int bit = << i;
if ((x & bit)) {
if (y & bit) num_or |= bit;
else num_xor |= bit;
num_and |= bit;
} else {
if (y & bit) num_and |= bit;
}
}
printf("3\n& %d\n| %d\n^ %d\n", num_and, num_or, num_xor);
return ;
}

对于以上位构造法:

  若f[i]:0->0,1->0,则f[i]=“&0,|0,^0”,即a[i]=0,b[i]=0,c[i]=0;

  若f[i]:0->0,1->1,则f[i]=“&1,|0,^0”,即a[i]=1,b[i]=0,c[i]=0;

  若f[i]:0->1,1->0,则f[i]=“&1,|0,^1”,即a[i]=1,b[i]=0,c[i]=1;

  若f[i]:0->1,1->1,则f[i]=“&1,|1,^0”,即a[i]=1,b[i]=1,c[i]=0。

可以直接构造a、b、c:

  a=f(0x0)|f(0x3ff);

  b=f(0x0)&f(0x3ff);

  c=f(0x0)&(0x3ff^f(0x3ff))。

参考程序如下:

#include <stdio.h>

int main(void)
{
int n;
int x = , y = 0x3ff;
scanf("%d", &n);
for (int i = ; i < n; i++) {
getchar();
char op = getchar();
int num;
scanf("%d", &num);
switch (op) {
case '&':
x &= num;
y &= num;
break;
case '|':
x |= num;
y |= num;
break;
case '^':
x ^= num;
y ^= num;
break;
default:
break;
}
}
int num_and = x | y,
num_or = x & y,
num_xor = x & (0x3ff ^ y);
printf("3\n& %d\n| %d\n^ %d\n", num_and, num_or, num_xor);
return ;
}

Codeforces 879C/878A - Short Program的更多相关文章

  1. Codeforces 878A - Short Program(位运算)

    原题链接:http://codeforces.com/problemset/problem/878/A 题意:给出n个位运算操作, 化简这些操作, 使化简后的操作次数不多于5步. 思路:我们可以对二进 ...

  2. Codeforces Round #443 (Div. 1) A. Short Program

    A. Short Program link http://codeforces.com/contest/878/problem/A describe Petya learned a new progr ...

  3. Codeforces Round #879 (Div. 2) C. Short Program

    题目链接:http://codeforces.com/contest/879/problem/C C. Short Program time limit per test2 seconds memor ...

  4. Codeforces Round #443 (Div. 2) C. Short Program

    C. Short Program time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  5. codeforces 879c

    C. Short Program time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  6. [Codeforces Round #443]Div2 C Short Program

    给你一串$n$个按顺序的位运算操作(&,|,^),形如"opt x",要求用不超过5行的位运算,按顺序操作出来和那个结果是一样的.$(n<=5e5,0<=x&l ...

  7. 【Codeforces Round #443 (Div. 2) C】Short Program

    [链接] 我是链接,点我呀:) [题意] 给你一个n行的只和位运算有关的程序. 让你写一个不超过5行的等价程序. 使得对于每个输入,它们的输出都是一样的. [题解] 先假设x=1023,y=0; 即每 ...

  8. Codeforces Round #443 (Div. 2) C: Short Program - 位运算

    传送门 题目大意: 输入给出一串位运算,输出一个步数小于等于5的方案,正确即可,不唯一. 题目分析: 英文题的理解真的是各种误差,从头到尾都以为解是唯一的. 根据位运算的性质可以知道: 一连串的位运算 ...

  9. 443 C. Short Program

    http://codeforces.com/contest/879/problem/C Petya learned a new programming language CALPAS. A progr ...

随机推荐

  1. 【loj10061】最短母串

    #10061. 「一本通 2.4 练习 4」最短母串 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 1bentong 提交    提交 ...

  2. springMVC的架构与执行流程

    SpringMVC术语 前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU. 处理器映射器(HandlerMapping):根据URL去查找处理器 处理器(Han ...

  3. 475 Heaters 加热器

    详见:https://leetcode.com/problems/heaters/description/ C++: class Solution { public: int findRadius(v ...

  4. RHEL 6.5----SCSI存储

    主机名 IP master 192.168.30.130 node-1 192.168.30.131 node-2 192.168.30.132 安装并启动 [root@master ~]# ll / ...

  5. PHP 讓 json_encode() 指定回傳格式

    PHP 回傳 JSON 很方便, 只要將資料經過 json_encode() 就解決了. 不過因為 PHP 自動轉換型別, 造成很多資料都習慣存成字串, 希望在輸出 JSON 的時候, 數字部份可以輸 ...

  6. Aappcloud 调到二级页面黑屏

    PartnerHead3.html 后面多了一个点

  7. PHP设计模式 观察者模式(Observer)

    定义 当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新. 模式要点 Event:事件 Trigger() 触发新的事件 abstract EventGenerator 事件产生者 Fu ...

  8. os模块详解2

    1.os.getenv('HOME')  读取操作系统环境变量HOME的值. 2.os.environ 返回操作系统所有的环境变量. 3.os.environ.setdefault(‘a’,‘b’) ...

  9. 找不到draw9patch.bat?已经不用找了

    Google 已经因为 draw9patch 热门的原因,把它集成在 Android Studio 里面了, 你现在可以直接在 Android Studio 里直接打开编辑了.

  10. uva10735 Euler Circuit

    题外话:很多混合图问题可以转化为有向图问题(将无向边拆为两条有向边) 本题不行,因为只能经过一次 这种问题能想到网络流.. 复习欧拉回路:入度==出度 和uva1380有点相似,要先给无向边定向.原图 ...