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;
}
相关推荐
xlp666hub1 天前
Leetcode第一题:用C++解决两数之和问题
c++·leetcode
ZhengEnCi1 天前
08c. 检索算法与策略-混合检索
后端·python·算法
程序员小崔日记1 天前
大三备战考研 + 找实习:我整理了 20 道必会的时间复杂度题(建议收藏)
算法·408·计算机考研
lizhongxuan1 天前
AI小镇 - 涌现
算法·架构
AI工程架构师1 天前
通常说算力是多少 FLOPS,怎么理解,GPU和CPU为什么差异这么大
算法
不想写代码的星星1 天前
C++继承、组合、聚合:选错了是屎山,选对了是神器
c++
祈安_1 天前
Java实现循环队列、栈实现队列、队列实现栈
java·数据结构·算法
归去_来兮2 天前
拉格朗日插值算法原理及简单示例
算法·数据分析·拉格朗日插值
千寻girling2 天前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法
颜酱2 天前
一步步实现字符串计算器:从「转整数」到「带括号与优化」
javascript·后端·算法