codeforces 879c
2 seconds
256 megabytes
standard input
standard output
Petya learned a new programming language CALPAS. A program in this language always takes one non-negative integer and returns one non-negative integer as well.
In the language, there are only three commands: apply a bitwise operation AND, OR or XOR with a given constant to the current integer. A program can contain an arbitrary sequence of these operations with arbitrary constants from 0 to 1023. When the program is run, all operations are applied (in the given order) to the argument and in the end the result integer is returned.
Petya wrote a program in this language, but it turned out to be too long. Write a program in CALPAS that does the same thing as the Petya's program, and consists of no more than 5 lines. Your program should return the same integer as Petya's program for all arguments from 0 to 1023.
The first line contains an integer n (1 ≤ n ≤ 5·105) — the number of lines.
Next n lines contain commands. A command consists of a character that represents the operation ("&", "|" or "^" for AND, OR or XOR respectively), and the constant xi 0 ≤ xi ≤ 1023.
Output an integer k (0 ≤ k ≤ 5) — the length of your program.
Next k lines must contain commands in the same format as in the input.
- 3
| 3
^ 2
| 1
- 2
| 3
^ 2
- 3
& 1
& 3
& 5
- 1
& 1
- 3
^ 1
^ 2
^ 3
- 0
You can read about bitwise operations in https://en.wikipedia.org/wiki/Bitwise_operation.
Second sample:
Let x be an input of the Petya's program. It's output is ((x&1)&3)&5 = x&(1&3&5) = x&1. So these two programs always give the same outputs.
这个题怎么讲呢,网上很多题解都用的一种方法,这就很没有意思,这时候我先讲一下我用的方法,可能比较蠢,实现起来也挺麻烦,不过好歹是a了
题意:这是一个程序,只会三种操作&、|、^, 先输入一个n,说明有n个操作,
直接看数据
- 3
| 3
^ 2
| 1 这个就意味着某个数x进行了三次操作,分别是x|3之后再x^2,在x|1,现在让你根据结果进行转换成至多5部操作的集合,
就是说上面的一系列步骤,我们可以化成x|3再x^2的两步操作- 当然这个操作可能会有很多,就是让你转化成5步以内的操作
- 好了讲思路了,首先这个题要一位一位的算,这个是我首先想到的,一位一位的操作,最后进行组合,就是我的思路;
首先看这个东西 x的某一位 或0 和 与1 都不会改变这一位 对吧
再看 x的某一位 或1 和 与0 都会使这一位必定发生改变 对吧
当这一位必定发生改变的时候,我之前在这一位上的所有操作都没了意义对吧,因为前面无论我怎么操作,我最后只要在这一位上|1或&0,那么这位的值就是确定的- 若是我在这一位上进行|0和&1操作,这一位的值不会发生改变,那么我们就可以跳过这个操作
- 也就是说我只要纪录下异或的操作就行了,每当我遇见&0和|1的时候我就清空我纪录的异或操作
- 拿这个例子
- 3
| 3
^ 2
| 1- 看到我的操作思路首先看 这是个或,或的是0000000011(二进制),那么就是说我的第一位和第二位必定会发生改变,我就把我的第一位和第二位更新成1,
再看第二步 异或0000000010 把0存进第1位的数组里面(装的是异或的操作 就是说第1位第1次异或0),
把1存进第2位的数组里面(就是说第2位第1次异或1)............
接下来看第三步 或0000000001 第一位是1就是说我的第一位必定会变成1,于是第一位前面的异或操作都可以清除了,因为这一位必定变成1,
其他位是0就是说我的其他位保持不变,
这时候我们的x第一位是1,异或操作的集合为空,第二位是1,异或操作的集合是{1},第三位...........
首先我们肯定是先进行或操作和与操作,还是那句话,确定了这一位是|1还是&0,前面的所有操作都没了意义,而|0和&1我又可以忽略,因为他们不改变这一位上的值
所以先进性或和与操作,最后才轮到异或操作
先看这一位上是1还是0,如果确定是1那么这一位就|1,就是说假设我现在知道第一位和第三位是1,那么我就|5就可以了,这样的话第一位和第三位就变成了1,而其他的位不会发生改变
若是这一位上是0,那么我就进行&操作,就是说我现在确定了第一位和第三位是0,那么我就可以&1111111010这样就把第一位和第三位变成了0,其他位不发生改变
最后处理每一位的异或操作集合,假设第一位的异或集合是{0,1,0}(这里说一下,异或操作是符合交换律和结合律的),那么第一位最后就是异或上1(0^1^0 = 1),若是这位的
假设第二位的异或集合是{0,0},那么第二位最后异或0(0^0 = 0)
最后把每一位异或1的加起来:假设第一位异或1,第三位异或1,其他位异或0,那么我最后异或5即可- 丑陋的代码:
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int arr[16];//纪录某一位上的值 这一位上是-1代表从来没发生过&0和|1的操作
vector<int> p[16];//纪录某一位上的异或操作,每当遇见|1和&0时清空
int pp[16];//纪录p[16]异或操作的结果
int main()
{
int n,i,j,k,x;
int res = 0;
char a = '&',b = '|',c = '^';
char ch;
scanf("%d",&n);
for(i = 0; i < 16; ++i)
arr[i] = -1;
//赋上初值
for(int c = 0; c < n; ++c)
{
getchar();
ch = getchar();
scanf("%d",&k);
for(i = 1,j = 1; i < 1024; (i <<= 1),++j)
{
if((i&k) && ch == '|')
{
//|1时进行处理
arr[j] = 1;
p[j].clear();
}
else if((i&k) == 0 && ch == '&')
{
//&0时进行处理
arr[j] = 0;
p[j].clear();
}
else if(ch == '^')
{
//插入异或操作
if((i&k))
x = 1;
else
x = 0;
p[j].push_back(x);
}
}
}
for(i = 1; i < 16; ++i)
{
int d = 0;
for(j = 0; j < p[i].size(); ++j)
d ^= p[i][j];
pp[i] = d;
//求每一位异或操作的最后结果
}
printf("3\n");
for(i = 1; i < 16; ++i)
{
//判断哪一位被强制转换成了1 这一位|1即可
if(arr[i] == -1)
continue;
if(arr[i] == 1)
res += 1<<(i-1);
}
printf("| %d\n",res);
res = 0;
for(i = 1; i < 16; ++i)
{
//判断哪一位被强制转换成了0 这一位&0即可
if(arr[i] == -1)
continue;
if(arr[i] == 0)
{
res += 1<<(i-1);
}
}
res = 1023^res;
printf("& %d\n",res);
res = 0;
for(i = 1; i < 16; ++i)
{
//最后输出每一位异或1的和
//就是第一位和第三位是1,其他位是0,输出^5
if(pp[i] == 1)
{
res += 1<<(i-1);
}
}
printf("^ %d\n",res);
}
-------------------------------------------------------------------------
之后我在看看别人的那个解法,想明白了今后再补上
codeforces 879c的更多相关文章
- Codeforces 879C/878A - Short Program
传送门:http://codeforces.com/contest/879/problem/C 本题是一个位运算问题——位运算的等价变换. 假设位运算符“&”“|”“^”是左结合的,且优先级相 ...
- 2021.1.23--vj补题
B - B CodeForces - 879B n people are standing in a line to play table tennis. At first, the first tw ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
- CodeForces - 261B Maxim and Restaurant
http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...
随机推荐
- 网站文章分享到微博,微信、qq空间--举例用织梦
有对应接口的,传递参数过去就行了,注意下面的{..},需要替换为你的内容,看参数名称你应该知道是什么东东 新浪地址接口http://service.weibo.com/share/share.php? ...
- 超详细的PS抠图方法
步骤: 1.打开图片,根据图片的特点选择抠图工具: 2.在图像上找到第一个定点,要求定点要完全暴露在画布中,并且是清晰可见的顶点: 3.抠取图像时,多边形套索的定点以及边线应该向内1-2个像素,为了避 ...
- Date时间
var date_obj= new Date(); alert(date_obj.toLocaleString()) //2017/12/26 上午1:10:54 var date_obj2= new ...
- Serial-mcu
任务: PC按下1键, mcu连续发送a, 当PC按下2键, 终止发送 查询: #include <reg52.h> #define uint unsigned int #define u ...
- callable与runable区别?switch char ?sql只查是否存在,sql复制表 ?反射 ? spring mvc 和spring 上下文区别?
中化技术部 2018.4.16 1. callable 和 thread 区别 实现Callable接口的线程能返回执行结果,而Runable 不可以 . Callable 的call方法允许抛出异 ...
- IntelliJ IDEA 配置svn
1.启用版本控制 2.在弹出的框中选择svn 3.下载并解压VisualSVN 下载地址:http://subversion.apache.org/packages.html#windows 4.i ...
- ros pluginlib 段错误
最近在重新回看ROS插件时,运行出现了段错误,发现是boost版本问题,我目前版本是1.66,应该调整至1.58版本,如果跟其他软件使用不同的boost版本时,可以把相应版本编译到本地,不instal ...
- Activiti任务认领
Activiti任务认领 TaskService taskService; taskService.setAssignee(String taskId, String userId);taskServ ...
- 利用Delphi-cross-socket 库提升kbmmw 跨平台开发
以前我写过了,通过httpsys 提升windows 下,delphi 多层应用.随着delphi 10.2 对linux 的支持,很多人也想在linux 下 发布kbmmw 服务器,但是官方仅通过i ...
- 2018.12.05 codeforces 948C. Producing Snow(堆)
传送门 维护一个堆. 每次先算出一个都不弹掉的总贡献. 然后把要弹掉的弹掉,并减去它们对应的贡献. 代码: #include<bits/stdc++.h> #define ri regis ...