尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

2021CSP-J前3道题解析

2021CSP-J前3道题解析 题意有很多小朋友我们要给他们那糖果我们那糖果的数量有最低和最高限制。拿完糖果后给每一位小朋友发一颗糖果重复这个过程直到篮子里剩余的糖果数量不足以分给所有小朋友此时篮中剩下的糖果会作为我们的奖励题目要求我们求出能拿到的这份奖励的最大数量。思路我们可以遍历区间内每一个糖果的总数并且开一个变量算出每种数量分糖后的剩余糖果不断更新剩余糖果的最大值。一旦超出循环就直接跳出最后输出最大剩余数。而且我们不需要去联想仍和算法因为这就是一道数学题代码#includebits/stdc.h using namespace std; int main(){ long long n,l,r;// n小朋友最少拿l颗糖最多拿r颗因为这题数据范围已经达到了1e9所以要开 // longlong cinnlr; int sum0; int maxn0; for(long long il;ir;i){ sumi%n;// 更新最大剩余糖果数量 if(summaxn)maxnsum;// 不满足条件就跳出循环 if(maxnn-1)break; } // 输出最多能剩下的糖果 coutmaxn; return 0; }但是用循环的做法只能拿到90分我们刚才说过了这是一道数学题数学题只需要把每个变量走一遍就行所以时间复杂度可以控制在O(1)代码#includebits/stdc.h using namespace std; int main(){ long long n,l,r; cinnlr; if(l/n!r/n) coutn-1;// 两个数除以n结果不一样就输出n-1 else coutr%n;// 两条边界除以n商相同答案要用我们能拿糖果的最大值对n取余 return 0; }题目解释给定长度为 n、下标从 1 开始的数组共有 Q 次操作操作分为两种1.修改操作总数不超过 5000 次第一种是将数组第 x 位数值改为 v并且改动是直接影响原数组2.查询操作不改变原数组并对当前数组排序输出原数组第 x 个元素排序后的位置。题目思路我们可以用能同时存数值与初始编号的动态数组保存初始数据再用一份副本代表当前数组的编号和数值一定要有序同时记录每个编号在有序列中的位置。修改数值时先从副本中移除对应元素修改数值后找到合适位置排序重新插入副本再次更新后续每个值对应位。查询时直接读取目标编号对应的位置然后输出结果就完成了。代码#include bits/stdc.h using namespace std; vectorpairint, int a; // 存原史值和下标 vectorpairint, int temp; // 维护有序序列 int n, q; int main() { cin n q; for (int i 0; i n; i) { int x; cin x; a.push_back({x, i}); } temp a; sort(temp.begin(), temp.end()); vectorint pos(n); // 记录每个原始下标在副本的位置 for (int i 0; i n; i) pos[temp[i].second] i; while (q--) { int k; cin k; if (k 1) { int x, y; cin x y; x--; int p pos[x]; for (int i p; i temp.size(); i) temp[i] temp[i 1]; temp.pop_back(); // 把数组整体往前移 for (int i p; i temp.size(); i) pos[temp[i].second] i; a[x].first y; // 查询新的插入位置 int ispos 0; while (ispos temp.size() temp[ispos] a[x]) ispos; temp.push_back({0, 0}); // 把数组整体往后移 for (int i temp.size() - 1; i ispos; i--) temp[i] temp[i - 1]; temp[ispos] a[x]; for (int i ispos; i temp.size(); i) pos[temp[i].second] i; } else { int x; cin x; x--; cout pos[x] 1 endl;//因为数从0遍历的所以输出时要1 } } return 0; }题意依次处理 n 台机器机器分为服务机与客户机。服务机地址不重复代表注册成功输出 OK重复输出 FAIL客户机地址存在已注册服务机则输出对应服务机编号不存在输出 FAIL。思路我们可以记录每一个成功的服务器地址和对应编号逐行读取每台机器的操作与地址。如果是服务机Server遍历已有服务机判断地址重复重复输出 FAIL不重复就存入容器并输出 OK若是客户机(Client)就查找匹配的地址找到就输出对应的地址找不到输出 FAIL。代码#includebits/stdc.h using namespace std; int n; vectorpairstring,ints; // 储存机地址与下标 int main(){ cinn; for(int i1;in;i){ string op,ad; cinopad; bool f0; if(opServer){ // 判断地址重复 for(int j0;js.size();j){ if(s[j].firstad){ f1; break; } } if(f)coutFAILendl; else{ s.push_back({ad,i}); coutOKendl; } }else{ bool f0; // 查找对应服务机 for(int j0;js.size();j){ if(s[j].firstad){ couts[j].secondendl; f1; break; } } if(!f)coutFAILendl; } } return 0; }
返回列表