PAT甲级练习笔记
- [算法笔记的点]
- [做题前注意的点]
- [算法笔记题目]
- C++标准模板库
- 1001 Rational Sum
- 1002 Read Number in Chinese
- 1003 List Grades
- 1004 Tree Traversals Again
- 1001 A+B Format
- 1002
- 1003 Emergency
- 1019 General Palindromic Number
- 1102 Invert a Binary Tree
- 1103 Integer Factorization
- 1090 Highest Price in Supply Chain
- 1094 The Largest Generation
- 1013 Battle Over Cities
- 1003 Emergency
- 1018 Public Bike Management
- 1030 Travel Plan
- 1072 Gas Station
- 1087 All Roads Lead to Rome
[算法笔记的点]
- scanf以空白符(空格、TAB)为结束标志,字符数组用s%读入时以空格和换行为读入结束的标志,c%可以读入空格和换行
- 对double型,输入是%lf,输出是%f(%lf倒也不会错)
- 三种实用的输出格式
- %md 不足m位的int型右对齐输出,前补空格,若超出m位则原样输出
- %0md 同上,补的时候用0补
- %.mf 保留m位小数(四舍六入五成双)当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:5前为奇数,舍5入1;5前为偶数,舍5不进(0是偶数)
- floor(double x) ceil(double x) 向下取整 和 向上取整
- round(double x) 四舍五入
- 冒泡排序 i:1~n-1 j: 0 ~ n-1-i 均取到等号
- 10^6 大小的数组开在外面
- memset(a,0,sizeof(a));只能赋0/-1 因为是按字节赋值,即对每个字节赋同样的值
- fill(a,a+10,6);
- gets() 用来输入一行字符串(gets识别换行符\n作为输入结束,因此scanf完一个整数后,要先用getchar接收换行符再用gets
- 空字符\0在使用gets和scanf的时候会自动添加;如果不是使用前二者比如getchar,务必在末尾添加\0
- sscanf(str,"%d",&n); sprintf(str,"%d",n); char会被整合成一个int
- 数组名称即数组首地址 a==&a[0]
- 引用不产生副本,仅仅是起了个别名
- 传地址实际上也只是传了一个usigned的整数,也是一个拷贝,改变地址的话要用引用
- 常量不可用引用
- cin.getline(str,100); getline(cin,str);
- 浮点数的比较(重要,要常看)
[做题前注意的点]
1.不能使用的C函数 itoa() gets()【怎么实现整行输入?】
2.不要出现任何汉字,哪怕是注释
3.输出格式问题
4.不能用的库函数itoa() gets()
5.尽量用scanf printf
6.注意变量的类型
7.段错误一般是数组越界了,可能是开的不够大
8.审题要仔细,数组大小不能开错
[算法笔记题目]
入门模拟
日期处理
直接从日期1一个个加到日期2,月份日期的处理是个二维数组注意一下
进制转换
P进制数x转换成十进制y
int y = 0, product = 1;
while(x!=0)
{
y+=(x%10)*product;
x/=10;
product*=p;
}
十进制数y转成Q进制数x
int z[40],num=0;
do
{
z[num++]=y%Q;
y/=Q;
}while(y!=0);
PS:
z要倒序输出;
使用do-while而非while的原因在于如果y=0,while则会直接跳出;
C++标准模板库
vector
- vi.push_back(i)
- vi.pop_back()
- vi.size()
- vi.clear()
- vi.insert(vi.begin()+2,-1)
- vi.erase(vi.begin()+3)
vi.erase(vi.begin()+1,vi.begin()+3)左闭右开
set
- st.insert(1)
- set< int >::iterator it=st.find(2)
- st.erase(st.find(100))
set< int >::iterator it=st.find(30);
st.erase(it,st.end()) - st.size()
- st.clear()
string
- string str1=“abc”,str2=“xyz”,str3;
str3=str1+str2; - str.insert(3,str2)
str.insert(str.begin()+3,str2.begin(),str2.end()) - str.erase(str.begin()+4)
str.erase(str.begin(),str.end()-1) - str.clear()
- str.substr(pos,len)从pos位开始,长度为len
- string::npos -1 find函数失配时的返回值
- str.find(str2)
str.find(str2,pos) 从pos位开始匹配 - str.replace(pos,len,str2)
str.replace(it1,it2,str2)
map
map< char,int >::iterator it=mp.find(‘b’);
printf("%c %d\n",it->first,it->second);
queue
q.push(x)
q.front()
q.back()
q.pop()
priority_queue
stack
s.push(x)
s.top()
s.pop()
pair
1001 Rational Sum
题目要求:输入若干个假分数,求总和,输出,可能有负数,并要求真分数形式。
自己解法:
读入string。实际可以以int-char-int形式读入,省去后面很多多余操作
判断负号
if(正)‘/’之前整数读出,‘/’之后整数读出,做加法
else ‘/’之前整数读出,‘/’之后整数读出,做减法
算完后若a为零直接跳出循环。这里实际有错,但测试的数据过了,a为零是恢复成初始状态
根据ab的绝对值大小辗转相除得出公因子,约分,读下一个数据
分子为0或分母为1直接输出分子,否则转换为假分数
简单解法
1002 Read Number in Chinese
1003 List Grades
题目要求:输入若干学生名字,课程号,分数,按成绩排序在给定分段内输出,没有则输出NONE
自己解法:结构体,sort,循环判断输出
注意点:题目可能考排序和查找,但系统sort()比自己写的冒泡或快排还要快;
做的时候脑子秀逗了一下,以为给定区间只会在排序的两端。。。
bool com(const s&a, const s&b) {
return a.grade > b.grade;//sort()函数排序用
}
1004 Tree Traversals Again
题目要求:
1001 A+B Format
自己解法:数字转字符
注意点:数字转字符时array用char,用stringstream进行转化,具体操作为
#include <sstream>
stringstream s;
int h;
s<<h;
s>>a[i];
1002
注意事项:有关最后一项输出格式问题,有count的话可采用
//最后一项不输出空格
count--;
if (count != 0)
printf(" ");
1003 Emergency
最短路径+单源点可达性
1019 General Palindromic Number
转换进制n,d
int a[100];
int len=0;
do{
a[len++]=n%d;
n/=d;
}while(n!=0);
1102 Invert a Binary Tree
后序遍历反转二叉树
void postorder(int root)
{
if(root==-1)
return;
postorder(Node[root].lchild);
postorder(Node[root].rchild);
swap(Node[root].lchild,Node[root].rchild);
}
1103 Integer Factorization
DFS
me:直接暴力dfs 26分(本来25,改了index,原来没考虑1),三个点超时
提高时间:先打表,预处理出所有不超过N的n^p
1090 Highest Price in Supply Chain
有个点没过去,把初始的最大深度数改为0就对了(因为相等情况下++了,若设初值为1反而成了2)
1094 The Largest Generation
落入经验主义的错误,hashtable++只在根节点进行了,但实际上这题对根节点并无特殊操作,每次做dfs都要++
1013 Battle Over Cities
联通块数-1似乎不行?好吧是正确思路,是代码错了
原来是置0多此一举了。影响第二次结果啊我天!我是蠢狗么
1003 Emergency
按照书上写三个点没过去
原来是最短路径条数和点权无关,应该放在更新点权的外面
明明这题用深搜简单很多。。。
1018 Public Bike Management
感觉用Dijkstra有点难写,最短路径每条都要具体
dij+dfs
每条最短路径相等时如何保存?
1030 Travel Plan
DIjkstra+DFS没啥问题啊,为啥会错
边界条件错了!!v==s 不是0!!
纯DFS也可以,只要换cost的时候把pre也换了就好了
1072 Gas Station
我的思路:多次改变起点的单源点可达性问题,大于阈值=不可达,无解决方案=未全部访问,最优方案=DFS比较,唯一的问题:G1和1号房子怎么表示,房子有1000个加油站10个,会不会重叠啊?
解法:不是有n嘛!!加个n+序号就可以了喂
char city1[5],city2[5];
u=getID(city1);
v=getID(city2);
哪几个加油站需要记录么?
可以记录也不用记录,总共也才m个加油站,枚举就可以了
有一个点过不去,应该是ds出了漏洞
是vis的问题重置vis在dij函数内就没问题,在循环体中就有问题,因为有个break出来的,这样就没重置到
1087 All Roads Lead to Rome
城市名称和数字间的转换,类似1034 head of gang