1001 A+B Format(int->string)
将int转化为string,通过字符串长度控制输出空格的位置。
string str = to_string(a+b);
1003 Emergency(图的实际应用)
1.判断是有向图还是无向图。
2.图的初始化 fill(G[0],G[0]+maxn*maxn,INF);
3.在结点v没有被访问,且G[u][v]可达的情况下,讨论中间点u是否会改变最短路径。
1010 Radix(溢出、二分法)
1.用long long存储数据,小于0即为溢出;const ll inf = (1ll<<63)-1;
2.理解Radix的意思,eg:十进制数的任意位最高只能为9;确认数位的最高和最低位,二分法实际上是对数位进行二分。
1012 The Best Rank(排名排序)
1.注意:if if 和 if else if 的逻辑关系。(不是第一次这个错误了)
2.sort()会打乱元素的顺序。
3.结构体中不同数组的相同位置之间的排序。(类似于python中同一维度的比较)
全局变量:
int indexx;
bool cmp(Node a,Node b){
return a.course[indexx]>b.course[indexx];
}
......
主函数:
for(indexx=0;indexx<4;indexx++){
sort(num,num+index,cmp);
......
}
1013 Battle Over Cities(无向图的遍历)
1.问题转化,添加的边数=连通块的数量-1;
2.无向图的遍历问题,用邻接表存储结点。
1018 Public Bike Management(DJ路径,计算点权(一开始全部操作,利用正负判断剩余还是需要)
1.注意题目:“Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. ”有两个全局约束变量。
2.题目中表示了“顺序”,不能只算总和,带回的车,不能重新补充之前缺少的车!!!(我的错误)要从后往前进行求和,计算需要的车need和剩余拉回的车remain。
3.DFS()中,边界条件注意要有return!!!
1019 General Palindromic Number(进制转换)
palindromic adj. 回文的
进制转换用do while()结构。
1021 Deepest Root(图的联通分量,树高)
1.遍历图的DFS()中,注意if(!vis())的位置。
2.新思路,用一个数组存储每个点作为树根的最大高度,和最大树高比较得到最后结果。
3.dfs()将树根作为参数传入,一直保持不变。
1023 Have Fun with Numbers(高精度与低精度乘法)
将低精度视为一个整体,所以最后的进位可能不止一位,要用while (本题乘数为2,不需要)
while(jin!=0){
a.push_back(jin%10);
jin/=10;
}
对于减法,去除高位的0,但是至少保留一位
while(c.len > 0 &&c.d[c.len-1] == 0){c.len--;}
1024 Palindromic Number(大整数存储,低位在前)
1.对于是否符合某一条件的判断题,记得对一开始的输入就进行判断!!!
2.将数的低位,存储在数组的低位。相加操作时,取两个数组的最大长度进行运算(高位数组都为0),记得初始化进位位为0!!!
3.结构体的初始化
1027 Colors in Mars
1.读懂题意,radix 13(0~9 and A~C instead of 16) 以13为基数。
2.注意边界(0~168)暗示题目,13*13=169.
1029 Median
1.本质上是序列合并问题,可以分别用i和j模拟两个序列的下标,在序列末尾添加一个极大值防止越界!(最好不要用索引与数组长度的判断,容易出错)
2.int类型的最大值是为0x7fffffff。
3.两个合并序列中位数位置上的数,必然是两序列相应位置上的较小值。
1030 Travel Plan(DJ+第二条件边权)
用c[maxn]记录最小花费,当满足条件时,直接用pre[v] = u,保存路径。
vector<int> pre; 若要直接使用下标索引,需要初始化pre.resize(n);
1031 Hello World for U
求解不等式,模拟过程,直到满足条件为止。
1032 Sharing
1."output the 5-digit starting position of the common suffix",输出五位,不够补零。printf("%05d\n",p);
2.int p;用for(p=开始;p!=结尾;p=下一个)
1033 To Fill or Not to Fill(贪心,“剩余讨论”)
1.将终点,排序后,放在整个数组的结尾。
2.设置下一结点的序列号为int nextt = -1; if(nextt==-1)break;表示没有找到下个可以去的结点。(类比DJ)
3.寻找下一节点时,for中约束条件,i<=n&&node[i].d-node[now].d<max_dist。同时设置minn为无穷大,保证如果下一结点可达,绝对存在最小油价。
4.逻辑关系
if(下一站油价更便宜){
if(是否油箱中还有油){
}
else{
}
}else{//本车站油价最低
在本站,将油箱加满
剩余油量 = 油箱容量-到达下一站的消耗
}
now = nextt;//到达下一结点
1034 Head of a Gang(图的全局遍历DFS)
1.读懂题目,注意边界,“通话记录的条数”==边数,所以结点的个数应为边数的两倍。
2.对于有环的路径计算问题:(可达与是否访问的关系)
先判断是否可达;可达后,将边权删除防止重复计算(针对无向边);再判断该结点是否访问过。
3.map本身会按照键值的大小顺序进行排序。
1036 Boys vs Girls
bool cmp(struct node a,struct node b){
if(a.sex!=b.sex)return a.sex>b.sex; //先分男女,女的在后
else return a.grade<b.grade; //再比较分数
}//只排序一次
1037 Magic Coupon(贪心)
两个数组不等长时,找到对应数组的末尾索引(设置为无穷大)并控制合理范围!!!
1039 Course List for Student
1.数组大小根据题目中的要求设定,“A student name consists of 3 capital English letters plus a one-digit number.”编号为三个英文字幕+一个阿拉伯数字,必然是26*26*26+10+1。
2.用哈希思想映射string和int之间的关系。如果用map<string,int> ans,对于没有放入的string str,ans[str] = 0;
1040 Longest Symmetric String
暴力法直接枚举:奇数和偶数可以放在一起讨论;最短回文字长度为1!!!
1042 Shuffling Machine
1.简单模拟,读懂题意,通过结果模拟推导,写点注释理清思路。
2.注意基数值,作为边界。
1045 Favorite Color Stripe(最长不降子序列)
1.对于顺序的转化,控制在1~m之间。
2.对于不在顺序范围内的元素,直接舍弃。(坑:不管设置成最大还是最小,都影响最终结果)
3.一种查补样例的思想:考虑不成立这一极端情况。
1046 Shortest Distance(正反两个方向)
反向用时 = 全部用时 - 正向用时
1048 Find Coins
双指针,i = 0;j=n-1 while(i<j) i与j不重合的时候,条件成立。
1053 Path of Equal Weight
1.书上代码有错,cmp分别对(每个非叶节点的子节点)进行排序,但是没有对(同一层的非叶节点的子节点)排序。注意,同层不同父亲结点的子节点的权值大小问题!
解决办法,使用vector<vector<int> > ans,存放所有路径;
//对每种情况按字典序从大到小排序:sort(ans.begin(), ans.end(), greater<vector<int>>());
2.按情况讨论sum与s的大小关系,注意要return ;
3.注意temp.push_back()和temp.pop_back()的位置,可以模拟DFS找图的最短路径。
1054 The Dominant Color
使用map进行映射。
1056 Mice and Rice(队列的应用)
1.同一放入同一个队列中处理,需要的从后再入队,不需要的出队。
2.排名的计算,重复写入,可以擦除之前的结果。
3.读懂题意!!!(maximal和the left be put into the last group 同时成立)
对于最后一组人不够的情况,可以用if(i*ng+j>=np)break;判断。
1060 Are They Equal(string的处理,大坑)
1.科学计数法是否相等,比较指数和底数部分。按照,是否为小于1的小数进行讨论!!!
0.000001 0.1*10^-5
2.按照整数部分,是否为零进行讨论。(需要统计位数)
3.string str.erase(s.begin()); 参数必须是迭代器;删除操作(自动连接) 单参数时,只删除那一位
4.方便确定精度,所以删除小数点。(与1073的区别)
1063 Set Similarity
1.set的使用,find()返回一个迭代器。参考写法:
for(auto it=sum1.begin();it!=sum1.end();it++){
if(sum2.find(*it)!=sum2.end())
//执行操作
}
写法2 for(auto it:sum2) cout<<it<<endl;
2.利用数学除法思想,计算重合百分率。
printf("%.1f",double(countt)/double(sum1.size()+sum2.size()-countt)*100);
3.the number of distinct common numbers重点在于common; the total number of distinct numbers重点在于distinct。读懂题意!!!
1064 Complete Binary Search Tree(树的综合运用)
1.完全二叉树性质:用数组从下标1开始存储完全二叉树,开辟数组注意边界,最下面一排叶子结点的子节点都为-1。
根结点为1,左子树为root*2,右子树为root*2+1;
判断某个结点是否为空结点的标志为:该结点下标root大于结点总个数n,递归时注意边界;
判断某结点是否为叶子结点的标志为:该结点下标root的左结点标号root*2大于结点总个数n。
2.二叉搜索树性值:其中序遍历为递增序列。
3.中序遍历的逆过程,将中序遍历访问到的结点,存储到完全二叉树的数组中。
1065 A+B and C (64bit)(long long溢出)
1.两个long long值相加的和,存储在另一变量中,再进行比较。
2.long long int 范围 [-2^(63),2^(63)),正溢出后的值为[-2^(63),-2),右边界为2^(64)-2 % 2^(64)得到。
1067 Sort with Swap(0, i)(贪心,模拟整个过程)
1.坑:0可能回到0位置(与不在其位的元素交换)
2.数组pos记录当前元素的位置。
3.“Given any permutation of the numbers {0, 1, 2,..., N−1}”数组从0~n-1,找不在其位的元素不需要从头遍历。(设置一个全局变量,累加)
1068 Find More Coins(01背包,从右往左遍历)
1.dp[]数组的意义:前0件物品放入任意空间大小v的价值,均为0。
2.choice[i][j]判断选取的情况,i从n到1表示从后往前看第i个物品的选取情况,j从m到0表示从容量m到0是否选取。
1071 Speech Patterns(字符串处理(1060类比)、map)
1.读懂题意!!!Here a "word" is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.
因此,一个“单词”可以被定义为一串连续的字母数字字符被非字母数字字符分隔,除了它出现在句首或句尾。words are case insensitive 不区分大小写。
2.对于字符串的处理,while or for的使用。需要用到中间的结果,用while!!! int i 为全局变量。
3.局部变量设置为string ss;等于每次新建一个空字符串。
4.map的输出:for(auto &v : ans) cout<<v.first<<endl;
for(map<string,int> iterator::it = ans.begin();it!=ans.end();it++)
1072 Gas Station
读懂题目!
“A gas station has to be built at such a location that the minimum distance between the station and any of the residential housing is as far away as possible.”
条件一:最短的路径越远越好。
1073 Scientific Notation(字符串的处理)
1.科学计数法,确定整数部分和指数部分。'E'所在的位置为exp。
2.对于指数为正的情况,考虑小数点的移动,可能存在小数或整数(不用输出小数点)
3.exp-3中,3表示相隔的数。
1074 Reversing Linked List(部分倒序输出)
1.统计有效结点的个数,直接从头到尾遍历即可,不需要像书上那样设置无效结点。
2.部分倒叙输出,注意分情况讨论。for循环的位置,需要倒叙的组数置于最外层。
1075 PAT Judge(排序坑题目)
1.看清题目条件:有提交但是没有编译通过,输出变为0;编译都为通过,不输出。
2.注意隐藏边界,都通过的零分应该被输出。
1076 Forwards on Weibo(有向图遍历)
1.搞清楚谁是爸爸,谁是儿子。
2.任何图的遍历,都要考虑环的情况,避免转圈。
3.bool vis[maxn] = {false};访问过一个顶点就标记,加入队列的每一个结点,都是要遍历的。避免出现要遍历还没遍历,重复添加的可能。
1077 Kuchiguse(字符串处理) suffix 后缀
1.对于有空格的输入,记得cin>>n;之后用getchar()吸收空格。
2.字符串数组处理,string s[maxn];输入的时候,getline(cin,s[i]);
3.多字符串的共同子序列,先求得其最短长度,用局部变量确定最终停留位置。
4.reverse(s[i].begin(),s[i].end());对于原数组已经发生了改变。
1078 Hashing(哈希)
1.素数的模板,if(a<=1) return false; 1不是质数。
2.Quadratic probing (with positive increments only) is used to solve the collisions.
二次探测(仅限正增量)用于解决冲突。
1081 Rational Sum(分数的四则运算)
1.输出的时候,按照整数、假分数、真分数进行讨论。
2.模板记住,分子为0时,令分母为1。
1084 Broken Keyboard(字符串比较)
1.两个字符串,首先想到暴力for。
2.hash表长度包含所有字符,一遍设置为ASCII码长度128。
1085 Perfect Sequence(二分查找、双指针)
读懂题意:be a perfect sequence if M≤m×p where M and m are the maximum and minimum numbers in the sequence, respectively.讨论的是一个序列中的最大值和最小值,序列可变,不一定从头开始。
二分查找:问题转化为,在一个给定的递增序列中,确定一个左端点a[i]和一个右端点a[j],如果a[j]<=a[i]*p成立,且j-i最大。即在一个for循环中,确定左端点,寻找右端点。寻找第一个大于目标(p*a[i])的值的下标。
暴力枚举,就是两个for。利用数组递增的性值,每次保存最长的数组长度,for(int j = i+cnt;j<n;++j),不用重复讨论!!!
upper_bound(a+i+1,a+n,(long long)a[i]*p) - a;//在a[i+1]至a[n-1]中查找第一个大于a[i]*p的数,返回其位置给j 返回的是地址,需要再减去数组a的首地址
1086 Tree Traversals Again(先序、中序建树)
利用栈的性质,先压入就是先序序列,输出是中序序列。
1087 All Roads Lead to Rome(图的综合大题,典)
1.pre[maxn]记录每个结点的最短路径下的前驱结点,通过DFS获取完整路径,注意DFS的写法。
2.查看题目是否对路径顺序有要求,比如必须从前往后。回头时候多余的车,不能回补之前的空缺。
3.当遇到多种情况的判断时,必然存在全局变量与对应的局部变量,比较其大小关系,决定情况的判断。
1088 Rational Arithmetic(分数的四则运算)
1.类比1081
2.注意
1089 Insert or Merge(输出中间结果!!!)
根据插入排序的性值解题:每次0~i的区间内是有序的,找到最后一个i,看往后的i+1到n-1位置上的元素与原数组元素是否相等。
插入排序,可能存在相等数,即两个元素相等,不进行移动的可能!!!
1.二者都是过程排序,下一次排序的结果可能和上一次排序的结果相同。(测试点二)
2.merge,insert都可以模拟过程,中间排序的区间用sort();
4.归并排序
直接对原序列进行模拟归并,i从0到n/k,每次一段段得sort(a + i * k, a + (i + 1) * k);最后别忘记还有剩余部分(针对奇数的情况)的sort(a + n / k * k, a + n);这样是一次归并的过程。
1093. Count PAT's
数量级超过1e5,双for必定超时
方法一:两次动态规划压缩。
方法二:所有PAT组合的数量是每个A左边P的数量*右边T的数量。
1094 The Largest Generation(树的DFS遍历)
for(int i=0;i<childd[root].size();i++)
DFS(childd[root][i]) //该点必然可达,if() return 相当于判断其是否为叶子结点
1095 Cars on Campus(大型排序)
1.注意cmp的写法,必须有返回值,不能相冲突(>=).
2.对于时间成对的选取,先确定有效数组,在有效数组内操作!!!
3.补零输出,用printf("%02d",a);
chronologically 按年代次序的
1096 Consecutive Factors(最长连续因子,模拟)
1.模拟题--暴力枚举(双指针!!!)不要被题目迷惑,只要求连续的数。
2.确定边界,考虑模拟的边界是否合适。最大因子本题设置为int maxn = (int)sqrt(n*1.0) + 1;
3.int 最大为2^31-1(最后一个测试案例)2 147 483 674
4.考虑特例。
题目中隐含信息:对于质数,自己本身是自己的最长连续因子,输出cout<<1<<endl;cout<<n<<endl;
1098 Insertion or Heap Sort(堆排序and插入排序)
考虑连续相同元素的情况。
1099 Build A Binary Search Tree(1064异曲同工,BST遍历)
1.题目给了左右子树的未知(只给了对应结点的父子关系!!!),利用静态树组建树。
2.利用中序遍历BST为递增的性值,反向建树。
1100 Mars Numbers(打表思想)
1.注意边界contains a number in [0, 169),13*13;For the next higher digit,十位和个位。
揣测题意!
2.geline()连同空格一块读取,直到换行符为止。
3.由于有getline的存在,开头输入个数的时候,注意读取换行符!!!scanf("%d%*c",&t);
4.极端情况,十三的倍数,个位不输出0!!!
1101 Quick Sort(快排性值)
1.核心问题:如何寻找主元。
2.方法一:开两个数组,minn[]从右往左寻找[j...n-1]中的最小值,maxx[]从左往右寻找[0...i]中的最大值。当minn[i]==maxx[i]时,说明该位置为主元。
2022年秋季赛 《The Second Run of Quicksort》承接此思想,利用性值解题。
如果"三个以上元素位置确定"或"两个元素位置确定并且包含第一个元素或最后一个元素中的其中一个",则为快排第二趟后的序列。
3.方法二:对原序列sort排序,逐个比较,当前元素没有变化并且它左边元素的最大值都比它小时,就可以认为它一定是主元。
4.测试点2:如果主元为0,输出主元的地方输出换行符。(奇葩)
1102 Invert a Binary Tree(二叉树遍历)
1.找根,根没有父亲结点。
2.invert n. v. adj. 倒置
1105 Spiral Matrix(矩阵的螺旋填充)
1.输入n、m必然是N的整数约数,搞清楚行、列的情况
2.环形输出,用while,控制边界(不会就画图)
3.对于完全平方数,最后一个数要单数输出!!!
1107 Social Clusters(并查集)
1.course[h]记录任意一个喜欢活动h的人的编号,course[h] = i表示i喜欢活动h;findFather(course[h])就是这个人所在社交网络的根节点。本质上,还是人绑人,媒介是活动!
2.看清题目:"Hence the people are numbered from 1 to N."从0开始,还是从1开始很关键!