2025 1-12
【题目信息】1.基础运算【新知识】【易错点】【代码】#include iostream using namespace std; const int MAX_T 1000; // 假设最大测试用例数 int main() { int T; cin T; int arr[MAX_T][2]; // 二维数组存储 for (int i 0; i T; i) { for (int j 0; j 2; j) { cin arr[i][j]; } } for (int i 0; i T; i) { // 正确的输出格式每个结果之间都有空格 cout arr[i][0] arr[i][1] arr[i][0] - arr[i][1] arr[i][0] * arr[i][1] arr[i][0] / arr[i][1] endl; } return 0; }【题目信息】2.序列逆序输出【新知识】数组开太大了 导致无法运行成功int arr[1000][1000]; // 这行代码有问题内存计算一个int在大多数系统是 4 字节1000 × 1000 1,000,000个int总内存 1,000,000 × 4 4,000,000 字节 ≈ 4 MB为什么会导致程序崩溃栈内存溢出局部变量函数内定义的数组在栈上分配栈大小限制Windows/Linux 默认栈大小通常是 1-8 MB你的数组就占了 4 MB再加上其他变量很容易超出栈限制症状程序编译通过运行时可能立即崩溃或输入后崩溃没有错误信息直接退出解决方案从易到难方案1减小数组大小最简单如果题目说 N ≤ 100可以int arr[100][100]; // 只有 40KB安全方案2改为全局变量次简单#include iostream using namespace std; const int MAX 1000; int arr[MAX][MAX]; // 全局变量在数据区不在栈上 int main() { // 现在可以安全使用 arr return 0; }方案3用 vector推荐#include iostream #include vector using namespace std; int main() { int T; cin T; // vector会自动在堆上分配内存 vectorvectorint arr(T); for (int i 0; i T; i) { int N; cin N; arr[i].resize(N); // 动态设置大小 for (int j 0; j N; j) { cin arr[i][j]; } } // 使用 arr... return 0; }动态数组的用法【易错点】【代码】int main(){ int T; int N; cout 请输入T: ; // 先输出提示 cinT; int arr[100][100]; int temp[100]; for(int i0;iT;i){ cinN;//一共有多少个数参加逆序 temp[i]N; for(int j0;jN;j){ cinarr[i][j]; } } for(int i0;iT;i){ for(int jtemp[i]-1;j0;j--){ coutarr[i][j] ; } coutendl; } return 0; }【题目信息】3.字符串压缩【新知识】【易错点】vectorstring str(T); // 用vector代替变长数组cin.ignore(); // 重要清除输入缓冲区的换行符【代码】void result (string str); int main(){ int T; cinT; cin.ignore(); string str[T]; for(int i0;iT;i){ getline(cin,str[i]); } for(int i0;iT;i){ result(str[i]); coutendl; } return 0; } void result(string str){ int arr[26]{0}; for(char c:str){ arr[c-a]; } for(int i0;i26;i){ if(arr[i]!0){ coutchar(ia); if(arr[i]1){coutarr[i];} } } }【题目信息】4.调研 活动【新知识】你实际上不需要二维数组arr[10000][10000]因为我们只需要知道每个村庄是否被选中不需要记住哪个学生选了哪个村庄【易错点】【代码】#include iostream using namespace std; int main() { int n, m; cin n m; // 只需要一维数组标记是否被选中 bool selected[100010] {false}; // 开大一点防止越界 for (int i 0; i m; i) { int k; cin k; for (int j 0; j k; j) { int village; cin village; selected[village] true; } } // 输出结果 bool has_output false; for (int i 1; i n; i) { if (!selected[i]) { if (has_output) cout ; cout i; has_output true; } } if (!has_output) { cout No result; } cout endl; return 0; }【题目信息】5.判断闰年【新知识】【易错点】【代码】#include iostream using namespace std; int main() { int year; cin year; // 判断是否为闰年 if (year % 400 0 || (year % 4 0 year % 100 ! 0)) { cout Yes endl; } else { cout No endl; } return 0; }【题目信息】6.病毒【新知识】people.find(new_virus.substr(j,n))!string::npos另外 这题主要思想在于病毒的所有旋转virusvirus中所有长度为n的子串【易错点】string::find()的返回值找到返回第一次出现的索引位置可能是0, 1, 2, ...没找到返回string::npos通常是 -1 或 4294967295问题当在索引0找到时find()返回0在if中就是false会错误地认为没找到【代码】【题目信息】7.超市选址【新知识】【易错点】【代码】int main(){ int n; cinn; int distance[105]; int cost[105]; for(int i1;in;i){ cindistance[i]; } for(int location1;locationn;location){//在这里面任选一个作为超市 int sum_distance0; for(int i1;in;i){//计算其他地方到这里的距离之和 sum_distancesum_distanceabs(distance[i]-distance[location]); } cost[location]sum_distance; } //找到里面下标最小且值也是最小的 int min_INT_MAX; int temp; for(int i1;in;i){ if(cost[i]min_){ min_cost[i]; tempi; } } coutdistance[temp] cost[temp]; }【题目信息】8.八进制【新知识】在C中默认状态下数据按十进制输入输出。如果要求按八进制或十六进制输入输出在cin或cout中必须指明相应的数据形式oct为八进制hex为十六进制dec为十进制。但是二进制没有默认的输出格式需要自己写函数进行转换。输入整数n , 则在C中couthexn; coutoctn; coutdecn; 会分别将整数n以十六进制、八进制和十进制的形式输出【易错点】【代码】int main(){ int N; cinN; coutoctN; }int main(){ int N; cinN; int weight1; int result0; while(N){ int tempN%8; resulttemp*weight; weight*10; N/8; } coutresult; }【题目信息】9.反转字符串中的单词【新知识】1.因为pos start表示空区间长度0pos start表示至少有一个字符表示从start到pos-1有字符需要反转。数学上区间[start, pos)的长度 pos - start如果pos - start 0有内容如果pos - start 0空区间ispunct()检测所有标点符号包括//又或者只要不是字母就是符号英文标点! # $ % ( ) * , - . / : ; ? [ \ ] ^ _{ | } ~2.if (pos start) {reverse(str.begin() start, str.begin() pos);} 是因为最后一个单词只要进行了反转 start就应该被赋值到pos的下一位 但是现在字符串都遍历完了 start却大于pos 证明有单词没有被反转 另外 记住 这里是大于而不是大于等于【易错点】1.首先不用截取 因为在这个字符串你直接规定是从哪到哪的坐标需要反转即可 另外截取的函数是字符串的函数得用字符串来引用 其次 里面的参数 一个是坐标 另一个是长度2.反转的函数reverse()不用字符串来引用 但是它里面得是迭代器 表示的坐标 其次他反转的区间是左闭右开3.其次为什么不能在里面直接判断 如果下标到了最后了 直接反转最后一个单词 因为下标最大都是str.size()-1 但是是开区间 所以不会反转到这里来 要单独拿出来 总结你的三点理解✅ 不用substr()直接在原字符串上操作reverse()接受迭代器参数✅reverse()是左闭右开这是最容易出错的地方✅ 不能在循环内用index str.size()-1因为左闭右开会漏掉最后一个字符【代码】int main(){ string str; getline(cin,str); int count0; int index0; int start0; for(char c:str){ if(c ||c!){ //reverse(str.substr(start,index-start).begin(),str.substr(start,index-start-1).end()); reverse(str.begin()start,str.begin()index); startindex1; } index;//记录坐标的 } if (index start) { reverse(str.begin() start, str.begin() index); } coutstr; }【题目信息】10.字典序最大的输出【新知识】栈 动态数组【易错点】如果栈空了 说明下一个最大值在第一个最大值的前面 所以此时下一个最大值的值并不准确 我们需要重新来计算【代码】#include iostream #include vector #include stack using namespace std; int main() { int n; cin n; vectorint a(n); for (int i 0; i n; i) { cin a[i]; } vectorbool pushed(n 1, false);//记录数字是否已入栈 stackint stk;//模拟栈 vectorint result;//存储结果序列 int cur_max n; // 当前还未入栈的最大值 for (int i 0; i n; i) { stk.push(a[i]); pushed[a[i]] true; // 更新cur_max找到最大的还未入栈的数 pushed[cur_max是来判断上一个最大值已入栈 while (cur_max 0 pushed[cur_max]) { cur_max--; } // 弹出所有≥cur_max的栈顶元素 因为我们已经更新了新的最大值 while (!stk.empty() stk.top() cur_max) { result.push_back(stk.top()); stk.pop(); // 如果栈空了更新cur_max if (stk.empty()) { cur_max 0; for (int j n; j 1; j--) { if (!pushed[j]) { cur_max j; break; } } } } } // 弹出剩余 while (!stk.empty()) { result.push_back(stk.top()); stk.pop(); } for (int i 0; i result.size(); i) { cout result[i] ; } cout endl; return 0; }