CCF-CSP 40-2 数字变换(transform)【C++】考点:预处理

题目

TUOJhttps://sim.csp.thusaac.com/contest/40/problem/1

思路参考:第40次CSP认证前四题 - Oaths - 博客园https://www.cnblogs.com/oaths/articles/19327767

核心思路

预处理:根据输入的n,m,k序列,计算出输入为0~511,经过m次g运算后的结果,后面直接查表即可

时间复杂度:O(512*m)

代码

可以再让AI总结一下代码逻辑:

1. 整体功能

  • 程序实现了对一个9位二进制数(0-511)经过m次变换后,能够根据变换结果反推出原始输入值

  • 使用预处理+查表的方式,避免对每个输入实时计算

2. 核心函数 F(x, m)

  • 输入:整数x(0-511)和变换次数m

  • 处理流程

    1. 将x转换为9位二进制字符串(高位补0)

    2. 分割成3组3位二进制:s1、s2、s3

    3. 将每组转换为十进制:a1、b1、c1

    4. 进行m次迭代运算:

      • a2 = b1

      • b2 = c1 XOR (((b1² + k[i]²) mod 8) XOR k[i])

      • c2 = a1 XOR (((c1² + k[i]²) mod 8) XOR k[i])

      • 更新a1、b1、c1

    5. 最终结果 = (a2 << 6) + (b2 << 3) + c2(组合成9位整数)

3. 主流程 solve()

  1. 读取输入:n(查询次数)、m(变换次数)、k数组(变换参数)

  2. 预处理建表

    • 遍历所有可能的输入值0-511

    • 计算每个值经过m次变换后的结果res

    • 建立映射:ans[结果] = 原始输入

  3. 查询输出

    • 对每个查询值a,直接从表中找出对应的原始输入

    • 按格式输出结果

4. 注意事项

  • 位运算优先级:<<优先级低于+,需要括号

  • 输出格式:空格分隔,最后一个数后无空格

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int N=5e5+5, M=1e3+5;
int k[M];
unordered_map<int,int>ans;

//经过m次g运算
int F(int x,int m) //warn:return int 
{
	string s="";
	while(x>0)
	{
		s+=to_string(x%2);
		x/=2;
	}
	reverse(s.begin(),s.end());
	while(s.size()<9) s="0"+s;
	string s1=s.substr(0,3);
	string s2=s.substr(3,3);
	string s3=s.substr(6,3);

	int a1=(s1[0]-'0')*4+(s1[1]-'0')*2+(s1[2]-'0');
	int b1=(s2[0]-'0')*4+(s2[1]-'0')*2+(s2[2]-'0');
	int c1=(s3[0]-'0')*4+(s3[1]-'0')*2+(s3[2]-'0');	
	int a2=0,b2=0,c2=0;
	for(int i=1;i<=m;i++)
	{
		a2=b1;
		b2=c1^(((b1*b1+k[i]*k[i])%8)^k[i]);
		c2=a1^(((c1*c1+k[i]*k[i])%8)^k[i]);
		a1=a2;
		b1=b2;
		c1=c2;
	}
	int ans=(a2<<6)+(b2<<3)+c2; //warn:+的优先级高于<<,所以要() 
	return ans;
}

void solve()
{
	int n,m; cin>>n>>m;
	for(int i=1;i<=m;i++) cin>>k[i];
	//输入是0到511(2^9) 
	for(int i=0;i<512;i++) {
		int res=F(i,m);
		ans[res]=i;
	}
	for(int i=1;i<=n;i++){
		int a; cin>>a;
		cout<<ans[a]; //直接查表得到输入 
		if(i!=n) cout<<" "; //warn:注意输出格式 
	}
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0);
	solve();
	return 0;
}
相关推荐
瞎折腾啥啊11 分钟前
CMake FetchContent与ExternalProject
c++·cmake·cmakelists
三品吉他手会点灯1 小时前
STM32 VSCode 开发-C/C++的环境配置中,找不到C/C++: Edit Configurations选项
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
来自远方的老作者1 小时前
第10章 面向对象-10.4 继承
开发语言·python·继承·单继承·多继承·super函数
逻辑驱动的ken1 小时前
Java高频面试考点场景题09
java·开发语言·数据库·算法·oracle·哈希算法·散列表
小手cool1 小时前
如何在Java中根据另一个配对集合对一个集合进行排序
java·开发语言
升鲜宝供应链及收银系统源代码服务1 小时前
OMS 订单模块重构正式文档(一)---升鲜宝生鲜配送供应链管理系统
java·开发语言·重构·生鲜配送源代码·生鲜供应链源代码
帅小伙―苏1 小时前
力扣42接雨水
前端·算法·leetcode
AI科技星2 小时前
精细结构常数α的几何本源:从第一性原理的求导证明、量纲分析与全域验证
算法·机器学习·数学建模·数据挖掘·量子计算
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
c++·算法·leetcode
MegaDataFlowers2 小时前
26.删除有序数组中的重复项
算法