2721. 【SDOI2010】外星千足虫 题解

题目描述

题目描述

公元2089年6月4日,在经历了17年零3个月的漫长旅行后,“格纳格鲁一号”载人火箭返回舱终于安全着陆。此枚火箭由美国国家航空航天局(NASA)研制发射,行经火星、金星、土卫六、木卫二、谷神星、“张衡星”等23颗太阳系星球,并最终在小行星“杰森星”探寻到了地外生命。宇航员在“杰森星”地表岩层下45.70米位置发现一批珍贵的活体生命样本,并将其带回检测。在带回的活体样本中,最吸引人的当属这些来自外星的千足虫了。这些虫子身躯纤长,身体分为若干节。受到触碰时,会将身体卷曲成圆环形,间隔一段时间后才会复原活动。
  有趣的还不止如此。研究人员发现,这些虫子的足并不像地球千足虫成对出现、总共偶数条——它们每节身体下方都有着不定数量的足,但足的总数一定是奇数条!虽然从外观难以区分二者,但通过统计足的数目,科学家们就能根据奇偶性判断出千足虫所属的星球。

作为J国派去NASA的秘密间谍,你希望参加这次研究活动以掌握进一步的情报,而NASA选拔的研究人员都是最优秀的科学家。于是NASA局长Charles Bolden出了一道难题来检测你的实力:
  现在你面前摆有1…N编号的N只千足虫,你的任务是鉴定每只虫子所属的星球,但不允许亲自去数它们的足。Charles每次会在这N只千足虫中选定若干只放入“昆虫点足机”(the Insect Feet Counter, IFC)中,“点足机”会自动统计出其内所有昆虫足数之和。  Charles会将这个和数mod 2的结果反馈给你,同时告诉你一开始放入机器中的是哪几只虫子。他的这种统计操作总共进行M次,而你应当尽早得出鉴定结果。

假如在第K次统计结束后,现有数据就足以确定每只虫子的身份,你就还应将这个K反馈给Charles,此时若K<M,则表明那后M-K次统计并非必须的。
  如果根据所有M次统计数据还是无法确定每只虫子身份,你也要跟Charles讲明:就目前数据会存在多个解。

输入

输入文件insect.in第一行是两个正整数N, M。
  接下来M行,按顺序给出Charles这M次使用“点足机”的统计结果。每行包含一个“01”串和一个数字,用一个空格隔开。“01”串按位依次表示每只虫子是否被放入机器:如果第i个字符是“0”则代表编号为i的虫子未被放入,“1”则代表已被放入。后面跟的数字是统计的昆虫足数mod 2的结果。
  由于NASA的实验机器精确无误,保证前后数据不会自相矛盾。即给定数据一定有解。

输出

输出文件insect.out在给定数据存在唯一解时有N+1行,第一行输出一个不超过M的正整数K,表明在第K次统计结束后就可以确定唯一解;接下来N行依次回答每只千足虫的身份,若是奇数条足则输出“?y7M#”(火星文),偶数条足输出“Earth”。如果输入数据存在多解,输出“Cannot Determine”。
  所有输出均不含引号,输出时请注意大小写。

样例输入

输入1:

3 5
011 1
110 1
101 0
111 1
010 1

输出1:

4
Earth
?y7M#
Earth

输入2:

5 7
01100 1
11000 1
10100 0
11100 1
00011 1
00000 0
11111 0

输出2:

Cannot Determine

提示

【数据规模和约定】
  对于20%的数据,满足N=M≤20;
  对于40%的数据,满足N=M≤500;
  对于70%的数据,满足N≤500,M≤1,000;
  对于100%的数据,满足N≤1,000,M≤2,000。

前置知识:

高斯消元法解异或方程组
bitset 优化

1. 高斯消元法求解异或方程组

这个 oi-wiki 上面有,我就不详细介绍了

2. bitset 优化

bitset 实际上就是一个位压的 bool 数组,将很多的 0/1 压缩到一个 int / long long 里面,就像高精度乘法一样,比起普通的 bool 数组,这个快大约 323232 倍。

标准库的 bitset

详见 oi-wiki 的说明

手写 bitset

因为有时候因为各种原因无法调用标准库时,我们可以手写 bitset, 当然,使用普通的 bool 数组也可以
作者很慢的手写 bitset 代码

struct bitset {private:typedef long long Node_t;Node_t num[maxsize / (sizeof(Node_t) * 8 )];public:bitset() {memset(num, 0, sizeof(num));}bool operator[] (int x) {int id1 = x / (sizeof(Node_t) * 8);int id2 = x % (sizeof(Node_t) * 8);return (num[id1] & (1 << id2)) != 0; }void set(int pos, bool val = true) {int id1 = pos / (sizeof(Node_t) * 8); int id2 = pos % (sizeof(Node_t) * 8); if (val) num[id1] |= (1 << id2);else  num[id1] &= ~(1 << id2);}bool test(int x) {int id1 = x / (sizeof(Node_t) * 8);int id2 = x % (sizeof(Node_t) * 8); return (num[id1] & (1 << id2)) != 0; }int size() {return maxsize;}bitset<maxsize> operator ^ (const bitset<maxsize>& _p) {bitset<maxsize> ret;for (int i = 0; i < maxsize; ++i) ret.set(i, (*this)[i] ^ _p[i]);return ret;}bitset<maxsize> operator ^= (bitset<maxsize> _p) {for (int i = 0; i < maxsize; ++i) set(i, (*this)[i] ^ _p[i]);return *this;}
};

正题

我们设第 iii 次使用 “点足机” 时测量的足的的虫子编号为 ki,1,ki,2,...,ki,qk_{i,1}, k_{i,2},...,k_{i,q}ki,1,ki,2,...,ki,q
再设地球的虫子的腿的个数为 000 外星虫子的腿的个数为 111,
这是不影响后面的答案的,因为最后要mod2\mod 2mod2

我们设 xix_ixi 为编号为 iii 的虫子的腿的个数,其中 x∈[1,2]x \in [1, 2]x[1,2]

我们可以列出这样的一个方程组
{∑i=1qk1,i×xi=b1(mod2)(1)∑i=2qk1,i×xi=b2(mod2)(2)...∑i=mqk+1,i×xi=b3(mod2)(m)\begin{cases} \sum_{i=1}^{q} k_{1, i} \times x_{i} = b_1(\mod{2}) (1)\\ \\ \sum_{i=2}^{q} k_{1,i} \times x_{i} = b_2(\mod{2}) (2)\\ \\ ... \\ \sum_{i=m}^{q} k+{1,i} \times x_{i} = b_3(\mod{2})(m)\\ \end{cases} i=1qk1,i×xi=b1(mod2)(1)i=2qk1,i×xi=b2(mod2)(2)...i=mqk+1,i×xi=b3(mod2)(m)
现在我们的目标是求解这个模方程,但是我们使用 观察,注意,启示 大法后发现,题目中要我们使用高斯消元法求解这个问题,很明显,高斯消元法是无法求解模方程的,所以我们就要继续推理。

一个简单的例子
我们考虑模方程
a×b=c(mod2)b∈0,1a \times b = c (\mod{2}) \\ b \in 0, 1 a×b=c(mod2)b0,1
可以证明,再模 222 意义下,我们发现了一个这样的等式
a×b=ca \times b = ca×b=c
和方程
a⨁b=ca \bigoplus b = cab=c
bbb 是同一个答案! (注 :⨁\bigoplus 表示 C++ 中的异或,也就是 ‘^’)

所以我们就成功的将同余方程组改成了异或方程组,最后我们可以使用高斯消元法就可以求解了。

还有一个问题:
“第K次统计结束后就可以确定唯一解” 怎么处理呢?
我们可以使用一个 ans, 每次执行 ans = max(ans, cur) 即可!

完整代码(我手写的 bitset 超时了qwq)

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <algorithm>
#include <bitset>using namespace std;//namespace STL {
//	template <const int maxsize>
//	struct bitset {
//		private:
//			typedef int Node_t;
//			Node_t num[maxsize / (sizeof(Node_t) * 8 )];
//		public:
//			bitset() {memset(num, 0, sizeof(num));}
//			bool operator[] (int x) {
//				int id1 = x / (sizeof(Node_t) * 8);
//				int id2 = x % (sizeof(Node_t) * 8);
//				return (num[id1] & (1 << id2)) != 0; 
//			}
//			void set(int pos, bool val = true) {
//				int id1 = pos / (sizeof(Node_t) * 8); 
//				int id2 = pos % (sizeof(Node_t) * 8); 
//				if (val) num[id1] |= (1 << id2);
//				else  num[id1] &= ~(1 << id2);
//			}
//			bool test(int x) {
//				int id1 = x / (sizeof(Node_t) * 8);
//				int id2 = x % (sizeof(Node_t) * 8); 
//				return (num[id1] & (1 << id2)) != 0; 
//			}
//			int size() {return maxsize;}
//			bitset<maxsize> operator ^ (const bitset<maxsize>& _p) {
//				bitset<maxsize> ret;
//				for (int i = 0; i < maxsize; ++i) ret.set(i, (*this)[i] ^ _p[i]);
//				return ret;
//			}
//			bitset<maxsize> operator ^= (bitset<maxsize> _p) {
//				for (int i = 0; i < maxsize; ++i) set(i, (*this)[i] ^ _p[i]);
//				return *this;
//			}
//	};
//	template <class Tp> void swap(Tp& a, Tp& b) {Tp t = a;a = b;b = t;}
//	template <class Tp> Tp max(Tp a, Tp b) {return a > b ? a : b;}
//	template <class Tp> Tp min(Tp a, Tp b) {return a < b ? a : b;}
//}//using namespace STL;
const int N = 1024;
char buf[2048];bitset<N> jz[2048]; // 矩阵
int n, m;#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, a, b) for (int i = (a); i <= (b); i++)int ans = 0;
int guess(void) { // 高斯消元法REP(i, 1, n) { // n 个未知数个数int cur = i;while (cur <= m && !jz[cur].test(i)) cur++;if (cur > m) return false;ans = max(ans, cur);if (cur != i) swap(jz[cur], jz[i]);REP(j, 1, m) if (i != j && jz[j].test(i)) jz[j] ^= jz[i];}return true;
}
int main() {scanf("%d %d", &n, &m);REP(i, 1, m) {int x;scanf("%s %d", buf, &x);FOR(j, 0, n) jz[i].set(j + 1, (buf[j] == '1'));jz[i].set(0, x);}int ret = guess();if (!ret) return printf("Cannot Determine") & 0;printf("%d\n", ans);REP(i, 1, n) printf("%s\n", jz[i].test(0) ? "?y7M#": "Earth");
}

所以就写完了,qwq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96500.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96500.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96500.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[RestGPT] RestGPT智能体

第3章&#xff1a;RestGPT智能体 欢迎回来&#x1f43b;‍❄️ 在第1章&#xff1a;配置与环境中&#xff0c;我们为RestGPT配备了必要的"钥匙和密码"&#xff1b;在第2章&#xff1a;OpenAPI规范(OAS)中&#xff0c;我们为它提供了与在线服务对话的"使用说明…

笔记本电脑Windows+Ubuntu 双系统,Ubuntu无法挂载Windows的硬盘 报错问题解决

目录 一、前情提要 二、解决方案步骤 第一步&#xff1a;进入Windows进行修复和检查。这是最关键的一步&#xff0c;目的是让Windows来检查和修复它自己的文件系统。 第二步&#xff1a;回到Ubuntu验证挂载 三、总结与预防 一、前情提要 网上找到许多解决方案&#xff0c…

加密货币与区块链:六大刑事重灾区

高鹏律师&#xff08;首席数据官&#xff09;数字经济团队创作&#xff0c;AI辅助在数字货币的世界里&#xff0c;一夜暴富的传说屡见不鲜&#xff0c;但顷刻间失去所有的悲剧也时有发生&#xff0c;现在&#xff0c;我将为您剖析加密货币与区块链领域的六大刑事风险重灾区&…

Spring Ai 1.0.1中存在的问题:使用MessageChatMemoryAdvisor导致System未被正确的放在首位

使用MessageChatMemoryAdvisor导致System未被正确的放在首位 如下是使用Spring Ai实现多轮对话的官方例子&#xff08;文档地址&#xff1a;https://docs.spring.io/spring-ai/reference/api/chat-memory.html&#xff09;&#xff1a;AutowiredChatMemoryRepository chatMemor…

全景式综述|多模态目标跟踪全面解析:方法、数据、挑战与未来

【导读】 目标跟踪&#xff08;Visual Object Tracking, VOT&#xff09;一直是计算机视觉领域的核心问题之一&#xff0c;广泛应用于自动驾驶、无人机监控、人机交互等场景。随着单模态方法在复杂环境下逐渐遇到瓶颈&#xff0c;多模态视觉目标跟踪&#xff08;Multi-Modal V…

怎么用pytorch训练一个模型,并跑起来

MNIST 手写数字识别 任务描述 MNIST 手写数字识别是机器学习和计算机视觉领域的经典任务&#xff0c;其本质是解决 “从手写数字图像中自动识别出对应的数字&#xff08;0-9&#xff09;” 的问题&#xff0c;属于单标签图像分类任务&#xff08;每张图像仅对应一个类别&#x…

Qt应用程序发布方式

解决的问题&#xff1a;在自己电脑上用QT Creator编译的exe文件放到其他电脑上不能正常打开的问题。1、拷贝已经编译好的exe应用程序到桌面文件夹。桌面新建文件夹WindowsTest&#xff0c;并且将编译好的软件WindowTest.exe放入此文件夹中。2、在此文件夹空白处按住Shift再点击…

Linux 软件编程(九)网络编程:IP、端口与 UDP 套接字

1. 学习目的实现 不同主机之间的进程间通信。在 Linux 下&#xff0c;进程间通信&#xff08;IPC&#xff09;不仅可以发生在同一台主机上&#xff0c;也可以通过网络实现不同主机之间的通信。要做到这一点&#xff0c;必须同时满足以下两个条件&#xff1a;物理层面&#xff1…

5.Kotlin作用于函数let、run、with、apply、also

选择建议 需要返回值&#xff1a;使用 let、run 或 with配置对象&#xff1a;使用 apply附加操作&#xff1a;使用 also非空检查&#xff1a;使用 let链式调用&#xff1a;使用 let 或 run Kotlin作用域函数详解 概述 Kotlin提供了5个作用域函数&#xff1a;let、run、with、ap…

嵌入式学习日记(32)Linux下的网络编程

1. 目的不同主机&#xff0c;进程间通信。2. 解决的问题1&#xff09;. 主机与主机之间物理层面必须互联互通。2.&#xff09; 进程与进程在软件层面必须互联互通。IP地址&#xff1a;计算机的软件地址&#xff0c;用来标识计算机设备 MAC地址&#xff1a;计算机的硬件地址&…

C#_接口设计:角色与契约的分离

2.3 接口设计&#xff1a;角色与契约的分离 在软件架构中&#xff0c;接口&#xff08;Interface&#xff09;远不止是一种语言结构。它是一份契约&#xff08;Contract&#xff09;&#xff0c;明确规定了实现者必须提供的能力&#xff0c;以及使用者可以依赖的服务。优秀的接…

vsCode或Cursor 使用remote-ssh插件链接远程终端

一、Remote-SSH介绍Remote-SSH 是 VS Code 官方提供的一个扩展插件&#xff0c;允许开发者通过 SSH 协议连接到远程服务器&#xff0c;并在本地编辑器中直接操作远程文件&#xff0c;实现远程开发。它将本地编辑器的功能&#xff08;如语法高亮、智能提示、调试等&#xff09;与…

C语言实战:从零开始编写一个通用配置文件解析器

资料合集下载链接: ​https://pan.quark.cn/s/472bbdfcd014​ 在软件开发中,我们经常需要将一些可变的参数(如数据库地址、端口号、游戏角色属性等)与代码本身分离,方便日后修改而无需重新编译整个程序。这种存储配置信息的文件,我们称之为配置文件。 一、 什么是配置…

车机两分屏运行Unity制作的效果

目录 效果概述 实现原理 完整实现代码 实际车机集成注意事项 1. 显示系统集成 多屏显示API调用 代码示例&#xff08;AAOS副驾屏显示&#xff09; 2. 性能优化 GPU Instancing 其他优化技术 3. 输入处理 触控处理 物理按键处理 4. 安全规范 驾驶员侧限制 乘客侧…

vivo“空间计算-机器人”生态落下关键一子

出品 | 何玺排版 | 叶媛不出所料&#xff0c;vivo Vision热度很高。从21号下午发布到今天&#xff08;22号&#xff09;&#xff0c;大众围绕vivo Vision探索版展开了多方面的讨论&#xff0c;十分热烈。从讨论来看&#xff0c;大家现在的共识是&#xff0c;MR行业目前还处于起…

Azure TTS Importer:一键导入,将微软TTS语音接入你的阅读软件!

Azure TTS Importer&#xff1a;一键导入&#xff0c;将微软TTS语音接入你的阅读软件&#xff01; 文章来源&#xff1a;Poixe AI 厌倦了机械、生硬的文本朗读&#xff1f;想让你的阅读软件拥有自然流畅的AI语音&#xff1f;今天&#xff0c;我们将为您介绍一款强大且安全的开…

用过redis哪些数据类型?Redis String 类型的底层实现是什么?

Redis 数据类型有哪些&#xff1f; 详细可以查看&#xff1a;数据类型及其应用场景 基本数据类型&#xff1a; String&#xff1a;最常用的一种数据类型&#xff0c;String类型的值可以是字符串、数字或者二进制&#xff0c;但值最大不能超过512MB。一般用于 缓存和计数器 Ha…

大视协作码垛机:颠覆传统制造,开启智能工厂新纪元

在东三省某食品厂的深夜生产线上&#xff0c;码垛作业正有序进行&#xff0c;却不见人影——这不是魔法&#xff0c;而是大视协作码垛机器人带来的现实变革。在工业4.0浪潮席卷全球的今天&#xff0c;智能制造已成为企业生存与发展的必由之路。智能码垛环节作为产线的关键步骤&…

c# 保姆级分析继承详见问题 父类有一个列表对象,子类继承这个列表对象并对其进行修改后,将子类对象赋值给父类对象,父类对象是否能包含子类新增的内容?

文章目录 深入解析:父类与子类列表继承关系的终极指南 一、问题背景:从实际开发困惑说起 二、基础知识回顾:必备概念理解 2.1 继承的本质 2.2 引用类型 vs 值类型 2.3 多态的实现方式 三、核心问题分析:列表继承场景 3.1 基础代码示例 3.2 关键问题分解 3.3 结论验证 四、深…

tensorflow-gpu 2.7下的tensorboard与profiler插件版本问题

可行版本&#xff1a; python3.9.23cuda12.0tensorflow-gpu2.7.0tensorboard2.20.0 tensorboard-plugin-profile 2.4.0 问题描述&#xff1a; 1. 安装tensorboard后运行tensorboard --logdirlogs在网页中打开&#xff0c;发现profile模块无法显示&#xff0c;报错如下&#x…