复试上机笔记(C++)

计算机考研复试上机准备的刷题笔记(主要是C++)

将int型转化为字符型char型:
int a;
char str[10];//只能用字符串数组,不能用string
sprintf(str,”%d”,a);//将int型的a转化为字符型存到str中
此时遍历str需写成for(int i=0;str[i]!=’\0’;i++){…}或strlen(str)

  1. 将string型转化为int型:
    头文件:#include
    例子:string a;
    int b=atoi(a.c_str());//必须要有.c_str(),否则报错
  2. 将string型转化为double型:
    头文件:#include
    例子:string a;
    double b=atof(a.c_str());//必须要有.c_str(),否则报错
  3. C++格式输出
    头文件:#include
    输出05:setw(2)< 输出两位小数:setiosflags(ios::fixed)<
  4. C++的sort()函数和reverse()函数
    头文件:#include
    对数组进行排序:
    int a[3];
    sort(a,a+3);//参数是排序的起始和结束地址,左闭右开。默认升序。
    reverse(a,a+3);//倒置数组,参数是起始和结束地址,左闭右开。反转后为降序。
  5. 字符大小写转换函数(最好不要用ascii,容易出错)
    例子:
    char c=’a’;
    cout< char c=’A’;
    cout<
  6. 将string型的字符串中的全部字母转化为大、小写:
    头文件:#include
    例子:string a;
    transform(a.begin(),a.end(),a.begin(),::tolower);
    //参数说明:字符串起始位置,字符串结束位置,将转换后的字符串放在哪里,转换为小写(::tolower)还是大写(::toupper)注意::。
  7. 判断是否是素数,判断到sqrt(i)就可以了,不需要判断到i-1。sqrt(i)最好写在循环外面,用一个变量存取,若直接写在循环里,则每循环一次,都会计算一次,时间复杂度较高,strlen函数也是如此。1不是素数,素数是只能被1和自身整除的大于1的正整数。
  8. 素数筛法:要求出从2到1000000的所有素数时使用。
    步骤:从 2 开始遍历 2 到 1000000 的所有整数,若当前整数没有因为它是某个小于其的素数的倍数而被标记成非素数,则判定其为素数,并标记它所有的倍数为非素数。然后继续遍历下一个数,直到遍历完 2 到 1000000 区间内所有的整数。此时,所有没被标记成非素数的数字即为我们要求的素数。
  9. 读入带有空格的string类型(不能用cin,cin读到空格会停止)
    例:string a;
    //如果上面还要输入别的,如数字等,则要加一句getchar();将回车读掉,再输入
    getline(cin,a);

    char str2[1024];
    cin.getline(str2,1024); //第二个参数 1024 为要读取的字符串的长度
  10. 对vector进行排序:
    头文件:#include
    #include
    例子:vector b;
    sort(b.begin(),b.end(),排序类型);
    //其中,排序类型有:less()--------升序
    greater()-----降序
    自定义bool sortfun(…,…)
    {
    return a }
    例子:对结构体数组自定义排序
    typedef struct{
    string name;
    int high;
    }stu;
    bool cmp(stu a,stu b)//排序函数,参数一般就两个
    {
    return a.high==b.high?a.name>b.name:a.high }
    stu s;
    sort(s,s+n,cmp);//调用函数排序
    //也可对vector s型排序:sort(s.begin(),s.end(),cmp);
  11. 当有浮点数参与运算时,特别注意要保持精度。
  12. 读取一个字符:p=getchar();
  13. 在C++里使用strcmp(str1,str2)函数
    头文件:#include
    例子:string str1,str2;
    if(strcmp(str1.c_str(),str2.c_str())==0)//必须得有.c_str(),否则报错
    cout<<”相等”;
  14. 计算a和b的最大公约数GCD(欧几里得算法)
    辗转相除法:
    int gcd(int a,int b)
    {
    return b==0?a:gcd(b,a%b);
    }
    if(gcd(a,b)==1)//表示a和b没有最大公约数
  15. a,b的最小公倍数,就是ab除以a,b的最大公约数。即ab/gcd(a,b)。
  16. 牺牲空间换时间法(即哈希)
    将输入的数字作为数组的下标,多设几个数组来节省时间。
    可以用map或pair<…,…>
  17. cin>>str读取字符串时,遇到空格结束;
    getline(cin,str)读取字符串时遇到\n结束,因此可用getchar();读掉上一条数据结束的回车。
  18. string型反转:
    头问件:#include
    string a;
    reverse(a.begin(),a.end());
  19. 字符串连接时,str+=temp;比str=str+temp快很多。
  20. 大整数阶乘(例:求N=1000的阶乘)
    int temp;//每一步的结果
    int b[3001];//用于存放结果
    b[0]=1;//初始化
    int cnt = 1;//结果的位数
    int c=0;//进位
    int i,j;
    for(i=2;i<=N;i++)//NN-1N-2*…21
    {
    for(j=0;j {
    temp=b[j]*i+c;//生成最终结果
    b[j]=temp%10;//更新每一位
    c=temp/10;//更新进位
    }
    while(c>0)//若还有进位
    {
    b[cnt++]=c%10;
    c/=10;
    }
    }
    for(i=cnt-1;i>=0;i–)
    printf("%d",b[i]);
  21. C++中substr用法:
    例子:string s=”0123456789”;
    string sub1=s.substr(5);//取出从下标5开始到结束的子串
    //sub1=”56789”;
    string sub2=s.substr(5,3);//取出从下标为5开始截取长度为三位的子串 ,sub2=”567”;
    21.全排列:深度优先搜索。Pta基础编程7-37(收藏了一篇博客)
    22.对于成对出现的,比如坐标(有x,y),工作(有对应的起点和终点)时,用pair a来定义,<>中的类型可改。a.first表示第一个int,a.second表示第二个int,与map有所不同,map第一个是键,第二个是值。访问map时通过 for(map::iterator it=a.begin();it!=a.end();it++)遍历,it->first取他的键,it->second取他的值。
  22. 闰年:能被4整除但不能被100整除 或 能被400整除
    即(year % 40&&year%100!=0)||(year%4000)
    24.求两个日期之间间隔的天数(注意闰年问题)
    step1.预处理(牺牲空间换时间)
    设定一个统一原点,如0年1月1日,先预算出每一个日期距离这个原点的天数,保存起来,即预处理。
    step2.取出要求的年份各自相对于原点的天数,相减即可。
    #include
    #include
    #include
    using namespace std;
    //宏定义判断是否是闰年
    #define ISYEAP(x) (x%40&&x%100!=0)||(x%4000)?1:0
    //给出每个月的天数,左边是平年,右边是闰年
    int dayofMonth[13][2] = {
    {0,0},
    {31,31},
    {28,29},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31},
    {31,31},
    {30,30},
    {31,31},
    {30,30},
    {31,31}
    };
    struct date{
    int y;
    int m;
    int d;
    void nextDay()
    {
    d++;
    if(d>dayofMonth[m][ISYEAP(y)])
    {
    m++;
    d=1;
    if(m>12)
    {
    y++;
    d=1;
    m=1;
    }
    }
    }
    };
    //保存预处理的天数[年][月][日]
    int buf[5001][13][32];//必须定义为全局变量,因为这个数组内存很大,若在main()函数或其他函数中定义会出现栈溢出
    int main()
    {
    //进行预处理
    date temp;
    temp.y=0;
    temp.m=1;
    temp.d=1;
    int cnt=0;//天数
    while(temp.y!=5001)
    {
    buf[temp.y][temp.m][temp.d]=cnt;
    cnt++;
    temp.nextDay();
    }
    int y1,y2,m1,m2,d1,d2;
    while(scanf("%4d%2d%2d",&y1,&m1,&d1)!=EOF)
    {
    scanf("%4d%2d%2d",&y2,&m2,&d2);
    cout< }
    }
    25.若要定义一个很大的内存的数组,如int buf[5001][13][32],则要定义为全局变量,不能定义在函数里或main()函数里,否则会出现栈溢出的现象,报错。
    26.Hash的应用就是将输入的数据作为数组的下标,牺牲空间换时间的方法。当输入的数据有固定区间时可用,如输入的数据在[-5000,5000]内,但是这时候有负值,所以要设置一个偏移量5000,hash数组下标在[0,10000]之间,使用时需要用数据+偏移量的方法。
    27.贪心算法:总是选择当前最优解,而不从整体上去把握。
    对于有开始时间和结束时间的,一般选择结束时间最早的为最优解。
    28.对于char str[20],输入为:scanf(“%s”,str),输出为:puts(str),自带换行。
    29.堆栈的应用:括号匹配、表达式求值
    30.哈夫曼树求出最小带权路径长度:利用堆存放结点集合。(王道机试指南)
    堆(用优先队列实现):头文件:#include
    大根堆:priority_queue Q;
    小根堆:priority_queue Q;
    代码:
    #include
    #include
    using namespace std;
    int main()
    {
    int n;
    while(scanf("%d",&n)!=EOF)
    {
    //用优先队列定义的一个小根堆que
    priority_queue que;
    int a[n];
    for(int i=0;i {
    cin>>a[i];
    //que放入元素后自动按照小根堆排序
    que.push(a[i]);
    }
    int w=0;
    while(que.size()>1)
    {
    int a=que.top();
    que.pop();
    int b=que.top();
    que.pop();
    w+=a+b;
    que.push(a+b);
    }
    cout< }
    }
    31.set既可以去除重复元素,又可以自动排序。
    set插入用.insert(x),不是push或push_back了。
    遍历set不能像数组一样,取下标遍历,不可以随机存取,而要用迭代器,正确写法如下:
    set res;
    for(set::iterator it=res.begin();it!=res.end();it++)
    cout<<*it<

set自定义排序规则:
struct cmp
{
bool operator()(int a,int b){
return a>b;
}
};
set arr;//排序规则改为递减排序

set自定义排序对象及规则:
class Person{
public:
Person(string name,int age){
this->myname=name;
this->myage=age;
}
public:
string myname;
string myage;
};//此处改为结构体也行
如:
struct Person{
string myname;
int myage;
Person(string name,int age):myname(name),myage(age){
};
};

struct cmp{
bool operator()(const Person& a,const Person& b){
return a.myage>b.myage;
}
};
set arr;//person对象按年龄递减排序
for(set::iterator it=arr.begin();it!=arr.end();it++)
cout 32.二叉树建树、遍历、还原树
例子:输入二叉树的前序和中序遍历,输出后序遍历
思路:根据前序和中序遍历序列可以还原为唯一一颗二叉树,即建树过程,然后再对其进行后序遍历。
#include
#include
using namespace std;
//树节点的结构体
struct Node{
struct Node *lchild;
struct Node *rchild;
char c;
}Tree[50]; //静态内存分配数组
//树节点的个数
int cnt=0;
//前序序列、中序序列
char str1[30],str2[30];
//创建节点
Node *create()
{
Tree[cnt].lchild=NULL;
Tree[cnt].rchild=NULL;
return &Tree[cnt++];
}
//根据前序、中序遍历,建树
Node build(int s1,int e1,int s2,int e2)
{//s1,e1为前序遍历的始末位置,s2,e2为中序遍历的始末位置
Node T=create();
T->c=str1[s1];//前序的第一个节点为根节点
int rootIndex;//根节点在中序中的位置
for(int i=s2;i<=e2;i++)
{
if(str1[s1]==str2[i])
{
rootIndex=i;
break;
}
}
//有左子树
if(rootIndex!=s2)
{
T->lchild=build(s1+1,s1+rootIndex-s2,s2,rootIndex-1);
}
//有右子数
if(rootIndex!=e2)
{
T->rchild=build(s1+rootIndex-s2+1,e1,rootIndex+1,e2);
}
return T;
}
//后序遍历
void postOrder(Node T)
{
if(T->lchild!=NULL)
postOrder(T->lchild);
if(T->rchild!=NULL)
postOrder(T->rchild);
printf("%c",T->c);
}
int main()
{
while(scanf("%s",str1)!=EOF)
{
scanf("%s",str2);
Node T=build(0,strlen(str1)-1,0,strlen(str2)-1);
postOrder(T);
}
}
33.二叉搜索树=二叉查找树=二叉排序树
34.建立顺序表、链表时,都要先给节点分配内存。要用到malloc
若定义的结构体为struct Node{},而非typedef struct{}Node;也就是没给结构体取名字的话,malloc就要写成(…)malloc(sizeof(struct Node));,若取了名字,则写成(…)malloc(sizeof(Node));
35.十进制转化为x进制:将十进制数除x取余,逆序输出结果即可。
X进制转化为十进制:将x进制的每一位数乘以他的权重,再求和,如1010(二进制)=0
2^0 + 1
2^1 + 0
2^2 + 1
2^3(十进制)。
X进制转化为y进制:通过十进制过度,即先转化为十进制,再转化为y进制。
36.连续输入字符串使用while(getline(cin,a))时,输入Ctrl+z即可停止输入。
37.字符串转化为浮点数时,若使用aotf会有精度差异,如12121.121212,只能输出12121.1。此时就遍历字符串,将每个数据拆为一个个字符串,最后遍历字符串输出。详见16-2
38.递归的实现笛卡尔积(详见15-1)
39.中缀表达式转前缀表达式 方法
(1) 需要申请两个栈:s1(存放数字)、s2(存放运算符);
(2) 从右边开始遍历表达式,数字放在s1中,运算符放在s2中;其中运算符放入法则:①如果s2当前是空的或者栈顶元素是“)”,直接放入;②如果当前的运算符优先级大于或者等于栈顶元素优先级,直接放入;③如果当前运算符优先级小于栈顶元素优先级,栈顶元素出栈并放入s1;④遇到“(”运算符出栈放入s1,直到遇到“)”,将“()”丢弃。
(3) 将s2中元素出栈放入s1中;
(4)s1中元素出栈重新组成表达式。
40.中缀表达式转后缀表达式 方法
(1) 需要申请两个栈:s1(存放数字)、s2(存放运算符);
(2) 从左边开始遍历表达式,数字放在s1中,运算符放在s2中;其中运算符放入法则:①如果s2当前是空的或者栈顶元素是“(”,直接放入;②如果当前的运算符优先级大于栈顶元素优先级,直接放入;③如果当前运算符优先级小于或者等于栈顶元素优先级,栈顶元素出栈并放入s1;④遇到“)”运算符出栈放入s1,直到遇到“(”,将“()”丢弃。
(3) 将s1中元素出栈放入s2中;
(4) s2中元素出栈重新组成表达式。
1、中缀计算前缀表达式
计算值从右往左,优先级大于等于栈顶元素时入栈
2、中缀计算后缀表达式
计算值从左往右,优先级大于栈顶元素时入栈

41.后缀表达式求值
设一个数据栈,从左至右遍历表达式,为数字的时候进栈,为操作符的时候出栈两个元素进行运算:次栈顶元素op栈顶元素,在将结果入栈。
42.前缀表达式求值(与后缀表达式相反)
设一个数据栈,从右至左遍历表达式,为数字的时候进栈,为操作符的时候出栈两个元素进行运算:栈顶元素op次栈顶元素,在将结果入栈。
43.中缀表达式求值
设一个数据栈,一个操作符栈。从左至右遍历表达式,为数字的时候进入数据栈,为操作符时,判断此运算符与操作符栈顶元素的优先级,若优先级高于栈顶元素,则入栈,若小于等于则操作符出栈,数据栈出栈两元素,次栈顶元素op栈顶元素,将结果入数据栈,将此操作符入栈。
43. 定义一个二维的动态数组,有10行,每一行是一个用一个vector存储这一行的数据。
所以每一行的长度是可以变化的。之所以用到vector(0)是对vector初始化,否则不能对vector存入元素。
vector< vector > Array( 10, vector(0) );
44.C++文件操作
头文件:#include
读取文件:ifstream srcFile(“in.txt”,ios::in);
if(!srcFile){ cout<<”ERROR”< 写入文件:ofstream destFile(“out.txt”,ios::out);
If(!destFile)
{
srcFile.close();//记得要关闭之前打开的文件
cout<<”ERROR”< }
Int x;
While(srcFile>>x)//读入文件里的数据
{}
destFile< 最后要记得关闭打开过的文件
destFile.close();
srcFile.close();
45.最大子列和问题pat7-1
遍历一遍数组,进行当前子列求和,若此时子列和大于最大和,则改变最大和,否则若此时子列和小于0,则将子列和还原为0(因为若带上这个负数,则后面只会变小,还不如不加来的大),若子列和小于最大值但是大于0,则继续下一次遍历。
46.求反序数
int Reverse(int x)
{
int res=0;
while(x!=0)
{
res*=10;
res+=x%10;
x/=10;
}
return res;
}
47.父节点的下标为子节点的下标除2,此时最好以1开头而非零。
48.STL中的建堆:
堆的构建:make_heap()
指定为小顶堆:greater()
默认大顶堆:less
注意:包含头文件algorithm, 同时要在每插入一个元素的同时维护堆
头文件:#include
例子:vector ve;
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
ve.push_back(a);
make_heap(ve.begin(),ve.end(),greater());//建立小根堆
}
访问时和vector一样cout<

或用priority_queue a;不过这样的话就不能随机访问元素,而只能访问堆顶元素,用a.top()访问。
49.用printf输出string类型字符串
string a;
printf(“%s”,a.c_str());
50.vector只适用于向尾部增删元素,deque既可以向头部增删元素,也可以向尾部增删元素。
51.pat数据结构7-25深度优先遍历
52. pat数据结构7-28搜索树判断
53.string a(str.size(),‘ ’);//将a设置为str字符串长度的空格。
54.大数字的进制转换,输入的是string类型的。机试书p83
55.C++中STL的全排列函数:例即将ab的全排列求出为ab ba.
头文件:#include
bool next_permutation(iterator begin,iterator end); 当当前序列不存在下一个排列时,函数返回false,否则返回true。
next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
例子:
string str;
while(cin>>str)
{
sort(str.begin(),str.end());
while(next_permutation(str.begin(),str.end()))
{
cout< }
}
56.判断字符串是否含有某个子串
str.find(“子串”,从哪个下标开始找);
若找到则返回找到的下标,否则返回string::npos
所以判断是否含有该子串,可写成if(str.find(“子串”,从哪个下标开始找)== string::npos)表示没找到。
57.map有find操作, map.find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
58.平方探测法:
哈希散列平方探测法
1.平方是先正再负,从1开始,取平方,12,-12,22,-22,…
2.探测的基准是以起始位置为准
3.开始时不能取模
注意:每次加减增量的时候,是对开始值(是多少就是多少,不取模)加减,而不是对每次运算后的数加减!!!
59.若想对map进行自定义排序,可以将map的值赋给vector >,然后对vector >排序,输出。
如:
map res;//想对res进行自定义排序
vector > temp(res.begin(),res.end());//赋值
sort(temp.begin(),temp.end(),cmp);//转换为对vector进行排序
//输出
for(int j=0;j cout< 60.string.find()函数,若找不到时,返回-1或返回string::npos
61. 每左移一位,相当于该数乘以2。如:a<<1相当于a=a*2
62. 操作数每右移一位,相当于该数除以2。如:a>>1相当于a=a/2
63. 函数:
char *strtok(char s[], const char *delim);
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
例如:strtok(“abc,def,ghi”,”,"),最后可以分割成为abc def ghi。
首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
例子:
//处理字符串,提取数字放入vect
string str=”1,2,3,5,4,6”;
char *t = (char )str.data();//相当于str.c_str(),只是没有’\0’结尾
char temp = strtok(t, “,”);
while(temp != NULL){
int i = atoi(temp);
vect.push_back(i);
temp = strtok(NULL, “,”);
}
补充:将char
转化为string:
例子:char
t=….
string s(t);
64.二分查找里面好用的函数
(1)binary_search函数
bool binary_search(a + begin, a + end, k, cmp);
必要条件:从a[begin]开始到a[end - 1]的序列是有序序列。(用cmp自定义顺序)
功能:在数组a中从a[begin]开始到a[end - 1]按照cmp函数来比较进行二分查找有没有一个数等于k。
返回值:如果有一个数等于k则返回值为true,否则为false
参数:
首地址(a + begin) 必要
末地址(a + end) 必要
需要搜索的值 必要
比较函数表示序列如何有序(多数情况下适用于对结构体的搜索) 选要
(2)lower_bound函数
lower_bound(a + begin, a + end, k, cmp);
必要条件:从a[begin]开始到a[end - 1]的序列是有序序列。
功能:在数组a中从a[begin]开始到a[end - 1]按照cmp函数来比较进行二分查找第一个大于等于k的数的位置,如果有第一个大于等于k的数则返回该数的地址,否则返回a[end]的地址。
返回值:地址。如果要转换为int,需减去数组a。
参数:
首地址(a + begin) 必要
末地址(a + end) 必要
需要比较的值 必要
比较函数表示序列如何有序(多数情况下适用于对结构体的搜索) 选要
(3)upper_bound函数
upper_bound(a + begin, a + end, k, cmp);
必要条件:从a[begin]开始到a[end - 1]的序列是有序序列。
功能:在数组a中从a[begin]开始到a[end - 1]按照cmp函数来比较进行二分查找第一个大于k的数的位置,如果有第一个大于k的数则返回该数的地址,否则返回a[end]的地址。
返回值:地址。如果要转换为int,需减去数组a。
参数:
首地址(a + begin) 必要
末地址(a + end) 必要
需要比较的值 必要
比较函数表示序列如何有序(多数情况下适用于对结构体的搜索) 选要

例子:
int a[1010]={0,1,7,7,7,13,100};//必须有序
cout<<”a数组从a[1]到a[n]这n个数中有7吗?”< cout<<”a数组从a[1]到a[n]这n个数中第一个大于等于10的数的下标?”<< lower_bound(a+1,a+n+1,10)-a< cout<<”a数组从a[1]到a[n]这n个数中第一个大于10的数的下标?”<< upper_bound(a+1,a+n+1,10)-a< 65.c++里的isdigit(char a)函数:
isdigit函数只能判断字符型是否是数字
66.max与max_element区别:
max(a,b),返回a,b两者之间的较大值
max_element(r, r+6),返回数组r中[0, 6)之间的最大值的迭代器,
使用max_element返回的值减去数组头地址即为该最大值在数组的序号
例子:
int a[6] = {5, 3, 2, 6, 1, 4};
int b = a[0];
int c = a[1];
cout< cout< cout<<max_element(a, a+6)< cout< cout<<min_element(a, a+6)< 67.leetcode简单题202:用快慢指针破除可能的无限循环(环路)。使用“快慢指针”思想找出循环:“快指针”每次走两步,“慢指针”每次走一步,当二者相等时,即为一个循环周期。此时,进行相应的判断等操作。
详见https://blog.csdn.net/qq_21815981/article/details/79833976
68.滑动窗口算法适用情况:https://www.zhihu.com/topic/20746237/intro
69.求最长回文子串用中心扩展法
70. int ans[s1 + s2] = {0};不支持时写下面这个
int
ans = new int[s1+ s2]{0};
71.leetcode539最小时间差:
先将所有时间的时间用分数表示,保存在数组中,然后排个序,遍历数组,结果初值设为min(最大时间和最小时间的差,24
60-(最大时间和最小时间的差)),因为有可能反向算时间差,再求最小时间差。
72.leetcode583即求最长公共子序列,下标要从1开始,则字符串开头要加一个‘ ’填充。
73.leetcode647.涉及到求回文子串的问题,可以用中心扩展法提高效率,注意分奇偶
74.STL函数之部分和函数partial_sum 。对于序列 a,b,c,d 产生序列 a,a+b,a+b+c,a+b+c+d。partial_sum() 会计算出输入序列中长度从1开始不断增加的序列的和,所以第一个输出值就是第一个元素,下一个值是前两个元素的和,再下一个值就是前三个元素的和,以此类推。
头文件:#include
使用方法:partial_sum(容器要计算的起始位置,容器要计算的结束位置,结果存放的起始位置,自定义函数)其中自定义函数可以不要
例子:partial_sum(vec.begin(),vec.end(), arr, cmp);
例子:
int op(int x, int y) {
return (x + y) % 26;
}
int main()
{
vector shift_sum(shifts);//初始化vector
//下面这句里的r表示从后遍历。倒序存储。若报错op则前面的op函数要加一个static,变为static int op(int x, int y) {}
partial_sum(shifts.rbegin(),shifts.rend(),shift_sum.rbegin(),op);
}
75.leetcode890.判断字符串a和b是否是模式匹配(模式匹配即形式相同的字符串,如aba和cdc模式匹配,而abb和abc不是模式匹配),用a.find(a[i])==b.find(b[i])来判断。查看每一个元素是否处于相同位置即可。
for(int i=0;i {
if(a.find(a[i])!=b.find(b[i]))
return false;
}
76. leetcode1081.返回字符串 text 中按字典序排列最小的子序列,该子序列包含 text 中所有不同字符一次。
输入:“cdadabcc”
输出:“adbc”
思路:先用map将输入串中每一个字符的个数算出来,再遍历字符串,设置一个set,每往结果串中添加字符时就往set里添加,将一个曾经未出现的字符添加进结果字符串,若当前字符小于结果字符串最后一个字符,则看看可不可以删除最后一个字符,若最后一个字符个数不为0,则可删除,将set中对应的也删去,一直这样知道当前字符大于结果字符串最后一个字符或结果字符串为空,将当前字符加入,个数减1,set加入。
77.求某一区间内满足某个条件的数时,有两种方案:
一是遍历该区间,求出满足条件的数。
二是遍历所有满足条件的数,看是否在该区间内。
78.memset使用时,需加头文件#include
79.汉诺塔移动过程C++实现
#include
#include
using namespace std;
void hannoi (int n, char A, char B, char C)  // 把A盘里面的圆圈转移到C盘里面【A–C】。
{
if (n == 1)
{
cout << “移动圆圈” << n << “从盘” << A << “盘” << C << endl;  //把最后一个圆环从起点盘移动到目标盘。
}
else
{
hannoi (n-1, A, C, B);  // 把N-1个圆环从起点盘移动到(当前)没有任何圆环的过度盘;通过B、C盘在此函数调用中调用位置的互换,来实现把N-1个圆环从A盘到B盘的转移【A–B】。
cout << “移动圆圈” << n << “从盘” << A << “盘” << C << endl;
hannoi (n-1, B, A, C);  // 把N-1个圆环从国度盘移动到目标盘(模仿1和2的操作方法来实现);通过A、B盘在此函数调用中位置的互换,来实现N-1个圆环从B盘到C盘的转移【B–C】。
}
}
int main()
{
int n;
cin >> n;
hannoi (n, ‘a’, ‘b’, ‘c’);
}
80.杭电oj1995:
汉诺塔问题,求N个盘子从A挪到C,求第K个盘子挪动的次数。
答案:第i个盘子也就挪动了pow(2,n-i)次。(记住)
80.杭电oj1996:
汉诺塔问题,求n个盘子的汉诺塔输出移动过程中所有会产生的系列总数。(系列是只要满足大盘在小盘上即可)
答案:每个盘子都有3个位置可选,在每个柱子上的排列顺序是一定的,所以一旦选定就是一种方式,所以n个盘子就会产生3^n种情况,输出就可以了
81. 杭电oj2064:
汉诺塔问题,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?
答案:有n个盘子,先将上面n-1个盘子移动最右边,f(n-1)次,再将第n个最下面的盘子移到第二根柱子,再将最右边n-1个移动到最左边,f(n-1)次,再将第n个盘子移到最右边,最后将n-1个盘子又移动到最右边,f(n-1)次,则f(n)=3*f(n-1)+2。f(1)=2.
82. 杭电oj2077:

答案:既然是汉诺塔,那就非常有可能与原来的汉诺塔问题有联系,手动推出n=1,2,3,4的移动次数分别为2,4,10,28,而原汉诺塔问题n=1,2,3时分别为2,8,26,有什么发现呢?
假设原汉诺塔的数列为x1[20],现汉诺塔的数列为x2[20],那么x2[i]=x1[i-1]+2。
83.杭电oj2175:

答案:
int main()
{
long long n,m;
while(cin>>n>>m)
{
if(n0&&m0)
break;
int i;
for(i=1;i<=n;i++)
{
if(m%2==1)//i=1时
break;
m/=2;//i>1时
}
cout< }
}
84.不输出科学计数法:
头文件#include
cout< 85.杭电oj1722:

答案:为两数之和减去他们的最大公约数
86.杭电oj2136:

答案:素筛。visited[]里存放的不是bool值了,而是这个素数出现的位置。(即第几个出现)

87.若想对map排序,可用priority_queue >t大小根堆。入队用t.push({i.second,i.first});

你可能感兴趣的:(复试上机笔记(C++))