博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5637 Transform
阅读量:5083 次
发布时间:2019-06-13

本文共 1507 字,大约阅读时间需要 5 分钟。

题意: 有两种变换:

  1. 改变此数二进制的某一位(1变成0 或者 0变成1)

  2. 让它与给出的n个数当中的任意一个做异或运算

给你两个数s, t,求从s到t最少要经过几步变换,一共m组查询

思路: 仔细观察会发现其实只与(s^t)有关,那么设x = s^t,那么x就是s和t二进制之间的差别(仔细想想就是s和t相同的位都是0, 不同的都是1,说明只要需要发生变化的位都是1),那么只需要用s^x就得到t了,所以只需要求最少变成x需要多少步,然后再加1就是答案了,那么答案就是从0变成x需要多少步。bfs一下即可。不过还要注意第一个变化条件,在bfs的写出来。

#include 
#include
#include
#include
#define pii pair
using namespace std;const int maxn = 1e6;const long long mod = 1e9 + 7;int res[maxn];int a[20];void bfs(int n){ memset(res, -1, sizeof(res)); res[0] = 0; queue
Q; pii cur, nex; cur.first = cur.second = 0; Q.push(cur); int x = (1 << 17); while (!Q.empty()) { cur = Q.front(); Q.pop(); for (int i = 0; i < n; i++) { nex.first = cur.first ^ a[i]; nex.second = cur.second + 1; if (nex.first < x && res[nex.first] == -1) { res[nex.first] = nex.second; Q.push(nex); } } for (int j = 0; j < 17; j++) { nex.first = cur.first ^ (1 << j); nex.second = cur.second + 1; if (nex.first < x && res[nex.first] == -1) { res[nex.first] = nex.second; Q.push(nex); } } }}int main(){ int T, n, m, s, t; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); bfs(n); long long ans = 0; for (int q = 1; q <= m; q++) { scanf("%d%d", &s, &t); t = s ^ t; ans = (ans + (long long)q * res[t]) % mod; } printf("%d\n", (int)ans); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/Howe-Young/p/5255603.html

你可能感兴趣的文章
JQuery创建规范插件
查看>>
AD 域服务简介(三)- Java 对 AD 域用户的增删改查操作
查看>>
Unity中Text渐变色,和Text间距
查看>>
P4932 浏览器
查看>>
Concurrency Kit 0.2.13 发布,并发工具包
查看>>
SQL Relay 0.50 发布,数据库负载均衡器
查看>>
Infinispan 5.3.0.Alpha1 发布
查看>>
设计模式学习笔记——原型模式(Prototype)
查看>>
算法普林斯顿
查看>>
Struts2之类范围拦截器和方法拦截器
查看>>
模型层(练习)
查看>>
XML解析技术研究(一)
查看>>
Qt 学习之路 :使用 QJson 处理 JSON
查看>>
NPOI操作Excel导入导出
查看>>
angularJS 移动端焦点图
查看>>
jvm 这我就能会了 擦
查看>>
实战技能:小小微信支付业务,何必虚惊一场
查看>>
17-1 djanjo进阶-路由,视图,模板
查看>>
Shell脚本8种字符串截取方法总结
查看>>
P3254 圆桌问题
查看>>