进阶10 分解质因数求出区间[a,b]中所有整数的质因数分解。输入两个整数ab。2ab10000每行输出一个数的分解形如ka1*a2*a3...(a1a2a3...k也是从小到大的)(具体可看范例)33 42*2 55 62*3 77 82*2*2 93*3 102*5代码#include iostream #include vector using namespace std; int main() { int a, b; cin a b; for (int k a; k b; k) { cout k ; int n k; bool first true; // 控制是否输出 * // 从 2 开始试除 for (int i 2; i * i n; i) { while (n % i 0) { if (!first) { cout *; } cout i; first false; n / i; } } // 如果最后 n 1说明它本身是一个质因数 if (n 1) { if (!first) { cout *; } cout n; } cout endl; } return 0; }总结从2开始不断试除由于允许除数相同并且都是从小的开始所以设置了while使得每次出现的都是最小的那个质因数注意输出格式 除了第一个之外后边都要先输出*再输出质因数。与那种不是第一组就先输出一个空行是同一种思路基础38 树问题描述明明是一家地铁建设公司的职员他负责地铁线路的规划和设计。一次明明要在一条长L的马路上建造若干个地铁车站。这条马路有一个特点马路上种了一排树每两棵相邻的树之间的间隔都是一米。如果把马路看成一个数轴马路的一端在数轴0的位置马路的另一端在L的位置那么这些树都种在数轴的整数点上即012…L上都种有一棵树。由于要设计建造地铁站的缘故所以需要把一些树移走明明为了移树的方便把地铁站的区域也建在了数轴上两个整数点之间由于有多条地铁线路地铁车站的区域可能会有部分的重合重合的区域明明将来会设计成一个大型的车站移树的时候不必考虑地铁站重合区域的问题。现在明明想请你帮一个忙他把车站区域的位置告诉你即告诉你数轴上的两个整数点在这两个整数点之间是车站的区域请你写一个程序计算出把所有车站区域两点之间的树移走以后这条马路上还剩多少棵树。例如马路长为10要建造2个地铁车站车站的区域分别是2到5和3到6原先的马路上一共有11棵树在2到5的位置上建车站后需要移走4棵树在3到6的位置上建车站后也需要移走4棵树但是3到6这个区域和2到5这个区域有部分重合所以只需移走1棵树即可这样总共移走的树是5棵剩下的树就是6棵。明明的问题可以归结为给你一条马路的长度和若干个车站的位置请你用程序计算出把树移走后马路上还剩多少棵树。输入说明你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据每组测试数据有多行每组测试数据的第一行有两个整数L1≤L≤10000和M0≤M≤100分别表示马路的长度和地铁车站区域的个数。接下来有M行每行有2个整数分别表示每一座地铁车站区域的两个坐标的。每组测试数据与其后一组测试数据之间没有任何空行第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。输出说明对于每一组测试数据你写的程序要求计算出一组相应的运算结果并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数即把树移走后马路上还剩下多少棵树。每组运算结果单独占一行其行首和行尾都没有任何空格或其他任何字符每组运算结果与其后一组运算结果之间没有任何空行或其他任何字符第一组运算结果前面以及最后一组运算结果后面也都没有任何空行或其他任何字符。 注通常显示屏为标准输出设备。#include iostream #include vector #include algorithm using namespace std; struct Station { int s, e; }; bool cmp(const Station a, const Station b) { return a.s b.s; } int main() { int L, M; while (cin L M) { if (M 0) { cout L 1 endl; continue; } vectorStation stations(M); for (int i 0; i M; i) { cin stations[i].s stations[i].e; } // 按起点排序 sort(stations.begin(), stations.end(), cmp); // 合并区间 int totalRemoved 0; int curStart stations[0].s; int curEnd stations[0].e; for (int i 1; i M; i) { if (stations[i].s curEnd) { // 重叠或相邻合并 curEnd max(curEnd, stations[i].e); } else { // 不重叠结算当前区间 totalRemoved (curEnd - curStart 1); curStart stations[i].s; curEnd stations[i].e; } } // 结算最后一个区间 totalRemoved (curEnd - curStart 1); cout (L 1 - totalRemoved) endl; } return 0; }区间合并问题重叠或相邻合并不重叠结算当前区间最后记得加上最后一段。这基本上是固定思路基础47 最大值问题描述为了培养明明对数学的热爱明明的爸爸经常想出一些简单有趣且富有数学思想的游戏给明明玩。有一次明明的爸爸在纸上写了N个数字有正整数、负整数和0。明明的爸爸给明明一个范围他可以选大于等于L1个且小于等于L2个的数字L1≤L2且这些数字必须是连续的。但是要求明明选出的数的和最大这样说明明可能不太明白于是明明爸爸就举了一个简单的例子。 例如有5个数字为“1”、“2”、“3”、“4”、“5”明明可以选择大于等于1个且小于等于2个的数字也就是说明明可以选择1个数字或者连续的2个数字。通过观察数字串最后我们会选2个数字4和5他们的和最大为9。 明明明白爸爸的意思后就开始玩起游戏来。但是他发现这个游戏看似简单其实还是有相当的难度因为数字越多选择数字个数范围越大则题目越难到后面明明有些不想玩了。于是明明就求助于你请你帮他写一个程序来求出和的最大值。 明明的问题可以归结为有N个数字从中选择出连续的M(L1≤M≤L2)个数求出它们之和的最大值。输入说明你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据每组测试数据有两行每组测试数据的第一行有三个整数N(0N≤20)、L1、L2(0L1≤L2≤N)N表示数字串中有多少个整数L1、L2表示可选数字个数的范围每组测试数据的第二行有N个整数整数大小的绝对值都小于等于100整数之间用一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。输出说明对于每一组测试数据你写的程序要求计算出一组相应的运算结果并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数即所求的最大值。每组运算结果单独形成一行数据其行首和行尾都没有任何空格每组运算结果与其后一组运算结果之间没有任何空行第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注通常显示屏为标准输出设备。#include iostream #include vector #include climits using namespace std; int main() { int N, L1, L2; while (cin N L1 L2) { vectorint a(N); for (int i 0; i N; i) { cin a[i]; } int maxSum INT_MIN; // 初始化为最小值防止全负数出错 // 枚举所有起始位置 for (int i 0; i N; i) { int currentSum 0; // 枚举从 i 开始长度从 1 到 L2但不超过 N-i for (int len 1; len L2 i len N; len) { currentSum a[i len - 1]; // 累加新元素 // 如果当前长度 L1更新答案 if (len L1) { if (currentSum maxSum) { maxSum currentSum; } } } } cout maxSum endl; } return 0; }外循环是起始位置内循环是长度防溢出条件当长度满足要求时可以存下数字和加上长度更新条件。基础84 删除字符问题描述从键盘输入一个字符串和一个字符将输入字符从字符串中删除输出新的字符串。如果字符串中没有此字符则原样输出字符串。输入说明输入两行第一行输入一个字符串第二行输入一个字符。字符串最多允许输入20个任意字符。输出说明输出删除字符后的字符串。char不能用getline读string又不能用于字符比较如何解决string line; getline(cin, line); // 第一行字符串 string charLine; getline(cin, charLine); // 第二行可能是一个空格 char c charLine[0]; // 取第一个字符#include iostream #include bits/stdc.h using namespace std; int main() { string old; //整行读入要用getline getline(cin,old); char delcin.get(); string s; for(size_t i0;iold.length();i){ if(old[i]!del){ sold[i]; } } coutsendl; return 0; }上边是用cin.get什么都不跳过包括换行符和空格更保险的办法#include iostream #include string using namespace std; int main() { string line; getline(cin, line); // 读字符串可能含空格 string charLine; getline(cin, charLine); // 读第二行一个字符可能为空格 char c charLine[0]; string result ; for (size_t i 0; i line.length(); i) { if (line[i] ! c) { result line[i]; } } cout result endl; return 0; }string不能直接比字符但是如果string只有一个字符则我的s【0】就是那个char可以换个方法去比还方便输入包括空格。基础100 纯粹合数问题描述明明的爸爸是一位数学家明明受他爸爸的影响从小就喜欢数学经常向他爸爸学习或请教数学问题。一天明明问他爸爸什么是合数明明的爸爸回答说“首先合数都是大于1的整数其次合数是除了1和其本身外还能被至少一个其他自然数整除的数例如‘4’这个数它除了能被1和4整除外还能被2整除因此‘4’就是合数但是‘3’就不是合数因为3只能被1和3这两个数整除因此‘3’不是合数。”聪明的明明很快就理解了他爸爸的意思于是又接着问他爸爸“那什么又是纯粹合数呢”明明的爸爸接着回答说“一个合数去掉最高位剩下的数是0或仍是合数再去掉剩下的数的最高位剩下的数还是0或合数这样反复一直到最后剩下的一位数仍为0或合数我们把这样的数称为纯粹合数。例如‘100’这个数它能被1、2、4、5、10、20、50、100整除因此100是个合数我们去掉它的最高位剩下的数是0其实剩下的应该是00但是前置0对一个整数来说没有意义因此前置0被舍去就剩下个位数上的0因此‘100’是一个纯粹合数。有趣的是100是最小的一个三位纯粹合数。再例如‘104’这个数104能被1、2、8、13、26、52、104整除所以104是个合数我们去掉它的最高位后剩下44能被1、2、4整除所以4也是合数所以‘104’是一个纯粹合数。但是‘101’就不是纯粹合数因为‘101’只能被1和101这两个数整除。”明明对他爸爸的回答很满意于是自己动手从100开始寻找纯粹合数他一共找到了100个纯粹合数调皮的明明开始反过来考爸爸了问他爸爸能否告诉他第2个大于等于100的纯粹合数是哪个第3个大于等于100的纯粹合数又是哪个……明明的爸爸被这个突如其来的问题给难住了他无法立刻回答出来于是请求你的帮助帮助他回答明明的这个问题。明明的问题可以归结为根据一个正整数n求出从100开始从小到大的第n个纯粹合数。输入说明你写的程序需要从标准输入设备通常为键盘中读入多组测试数据每组测试数据仅占一行每行仅包括一个正整数n1 ≤ n ≤ 100。每组测试数据与其后一组测试数据之间没有任何空行第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。输出说明对于每一组测试数据你写的程序需要计算出一组相应的运算结果并将每组运算结果依次写入到标准输出设备通常为启动该程序的文本终端例如Windows中的命令行终端中。每组运算结果为一个整数即从100开始从小到大的第n个纯粹合数。每组运算结果单独形成一行数据其行首和行尾都没有任何空格每组运算结果与其后一组运算结果之间没有任何空行第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。#include iostream #include bits/stdc.h using namespace std; //判断是否合数 bool isHeshu(int n){ if(n2) return false; //注意 被2整除 也就是2的偶数 肯定都是合数 //所以 虽然2不是合数但是i依然要从2开始取否则就会漏掉很多偶数 for(int i2;i*in;i){ if(n%i0){ return true; } } return false; } //判断是否是纯粹合数 bool ispureHeshu(int n){ if(!isHeshu(n)) return false; string n_strto_string(n); //去掉最高位 for(int i1;in_str.size();i){ string new_strn_str.substr(i); int numstoi(new_str);//转为数字 if(num!0!isHeshu(num)){ return false; } } return true; } /* int转string类型用to_string而string转int型用stoi没有itos函数 */ int main() { int n; //100不算小 把握不住i的上限那就预存 vectorint ans; for(int i100;ans.size()100;i){ if(ispureHeshu(i)){ ans.push_back(i); } } while(cinn){ coutans[n-1]endl; } return 0; }基础120 顺序的分数问题描述输入一个自然数N请写一个程序来增序输出分母小于等于N的既约真分数(即无法再进行约分的小于1的分数)输入说明单独的一行一个自然数N(1..20)输出说明每个分数单独占一行按照分数大小升序排列对于分子为0的分数仅输出0/1不输出其它分母的分数比如0/2, 0/3。#include iostream #include bits/stdc.h using namespace std; //自定义排序 结构体 struct fru{ double fz; double fm; }; //增序排列 bool comparefru(const fru a,const fru b){ return a.fz*b.fmb.fz*a.fm; } //最大公约数 关于分数 要有最简分数的判断 int gcd(int a,int b){ //a b---b a%b while(b!0){ int tempb; ba%b; atemp; } return a; } int main() { int N; cinN; vectorfru f; //分母1-N for(double i1;iN;i){ //分子 for(double j0;ji;j){ if(j0){ if(i1){ f.push_back({0,1}); continue; }else{ continue; } }else{ if(gcd(j,i)1){ f.push_back({j,i}); } } } } sort(f.begin(),f.end(),comparefru); for(int i0;if.size();i){ coutf[i].fz/f[i].fmendl; } return 0; }记住最大公约数 如何判断翻译恶意软件变体的指数级增长对网络安全构成了严重威胁使得传统的基于签名的检测方法日益失效。虽然启发式和行为分析提供了一些改进但它们往往受限于高误报率且无法检测零日攻击。最近深度学习 (DL) 已成为一种强大的恶意软件检测范式能够无需人工特征工程直接从原始数据中自动学习复杂特征。本综述全面概述了应用于恶意软件检测的深度学习技术。我们根据输入数据表示如操作码序列、二进制图像、API 调用图和所使用的神经网络架构如 CNN、RNN、自编码器、GAN对现有方法进行了系统分类。此外我们讨论了关键挑战如对抗性攻击、类别不平衡以及大规模标注数据集的缺乏。最后我们概述了未来的研究方向包括用于安全的可解释人工智能 (XAI) 以及针对逃避技术的鲁棒防御机制。恶意软件Malware是恶意软件的简称包括病毒、蠕虫、木马、勒索软件和间谍软件旨在破坏操作或窃取敏感信息。恶意软件的格局正在迅速演变攻击者现在使用多态和变形技术不断改变代码结构从而逃避静态签名检测。因此迫切需要能够泛化到未见变体的智能检测系统。传统的机器学习 (ML) 方法如支持向量机 (SVM) 和随机森林已被广泛使用。然而它们的性能严重依赖于手工特征的质量这需要领域专业知识且耗时。相比之下深度学习 (DL) 模型擅长表示学习能够自动从原始二进制文件或反汇编代码中提取层次化特征。例如卷积神经网络 (CNN) 可以将恶意软件二进制文件视为图像以捕捉空间模式而循环神经网络 (RNN) 可以建模指令流中的序列依赖关系。尽管结果令人鼓舞但在网络安全中部署深度学习仍面临独特的障碍。一个主要担忧是对抗鲁棒性攻击者可以注入良性字节或修改指令以欺骗分类器而不改变恶意软件的功能。此外深度学习模型的“黑盒”性质使得安全分析师难以信任检测结果凸显了可解释性的需求。本综述旨在通过提供当前方法的结构化分类并识别开放性挑战弥合深度学习和安全社区之间的差距。单词