一些基础知识
C风格的字符串
- 输入输出scanf,printf
- 字符数组中,'\0’是正文结束的标志
- String var = str 将C语言风格的字符串,转化为C++风格的字符串
- var.c_str() 将C++风格的字符串 转化为C风格的字符串
注意:
- scanf只能读取一个单词,遇到一行字符包含多个单词则失效
- fgets(buf,100,stdin); 可以读取一整行字符,包括换行符
字符串操作
连接、删除、清空操作
find操作
数组的限制:
- 数组在定义时就要指定大小,这个大小还必须是常量
- 函数内部定义的数组不能太长,太长的要声明全局变量
pass:内存中不同模块的功能:
1.栈中存放的是局部变量,容量小,速度快
2.数据段中存放的全局表里,容量大。
vector的用法之前总结过:
1.vector C++风格的容器,类似于动态数组
2.vector vec3(10000); // 下标0-9999 默认初始均为0
3.push_back 尾部扩容 效率最高
4.pop_back 尾部删除
5.size()表示当前的容量
6.insert() 以及erase()
完数与盈数(清华上机题)
题目链接:http://t.cn/AiKEyQWW
题目:
描述
一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1。则称其为“完数”;若因子之和大于该数,则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。
输入描述:
题目没有任何输入。
输出描述:
输出2到60之间所有“完数”和“盈数”,并以如下形式输出: E: e1 e2 e3 …(ei为完数) G: g1 g2 g3 …(gi为盈数) 其中两个数之间要有空格,行尾不加空格。
代码
利用vector解题:
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
using namespace std;
//所有因子求和
int Sum(int i){
int sum=0;
for(int j = 1;j<i;j++){
if(i%j==0) sum=sum+j;
}
return sum;
}
int main(){
vector<int> Evec;//完数
vector<int> Gvec;//盈数
for(int i=2;i<=60;i++){
if(i==Sum(i)){
Evec.push_back(i);
}
else if(i<Sum(i)){
Gvec.push_back(i);
}
}
// 设置打印格式
printf("E:");
for(int i=0;i<Evec.size();i++){
printf(" %d",Evec[i]);
}
printf("\n");
printf("G:");
for(int i=0;i<Gvec.size();i++){
printf(" %d",Gvec[i]);
}
printf("\n");
}
约瑟夫问题
涉及到队列,复习一下队列的常用操作:
首先 #include
声明队列 queue myQueue
push操作 入队
myQueue.empty() 判空操作
myQueue.front() 队首元素
myQueue.pop() 删除元素
题目:
代码:
PASS:一定要仔细,我的天哪,一点小错误找了一个小时
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <queue>
using namespace std;
int main(){
// n个小孩,从编号p的小孩开始报数,报到m时,小孩出列
int n,p,m;
while(true){
scanf("%d%d%d",&n,&p,&m);
if(n==0 && p==0 && m==0) break;
queue<int> children; //队列中的元素是孩子的编号
// 把第一轮要喊编号的孩子排好队
for(int i=p,j=0;j<n;j++){
// i用来遍历孩子的编号
// j用来记录孩子喊的号
children.push(i);
i++;
if(i>n){
i=1;
}
}
// 喊号的过程
int num = 1;
while(true){
int cur = children.front(); //队首孩子的编号
children.pop();//喊完了出队
//检查喊的号码是不是m
// 如果是m
if(num == m){
num = 1;
// 喊号的同学不需要归队了
// 如果该生 出队之后,队列里没有人了
if(children.empty()){
// 最后一个同学出来了
printf("%d\n",cur);
break;
}
else{
// 还有同学在喊号
printf("%d,",cur);
}
}
//不是m
else{
// 再把它入队
num++;
children.push(cur);
}
}
}
}
猫狗收容所
题目:
代码:
结构体和队列的综合
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <queue>
using namespace std;
struct Animal{
int num;
int seq;
};
int main(){
queue<Animal> catQue;
queue<Animal> dogQue;
int seq = 0;
int n;
// n是操作序列的次数
scanf("%d",&n);
for(int i=0;i<n;i++){
// method 第一个元素 type第二个元素
int method,type;
scanf("%d%d",&method,&type);
// 若第一个元素是1,则代表有动物进入收容所
if(method==1){
if (type>0){
//处理狗
Animal dog;
dog.num = type;
dog.seq = seq;
seq++;
dogQue.push(dog);
}
else{
//处理猫
Animal cat;
cat.num = type;
cat.seq = seq;
seq++;
catQue.push(cat);
}
}
// 若第二个元素是2,则代表有人收养动物
else{
//出队
if(type == 0){
//不区分猫狗领养
// 1.无猫无狗
if(catQue.empty()&&dogQue.empty()){
continue; // 跳过本次循环体的剩余代码
}
// 2.收养狗 狗非空 猫为空
// 狗非空 猫非空 队首狗的序列号小一点
else if(catQue.empty() || !catQue.empty() && dogQue.front().seq < catQue.front().seq){
printf("%d ",dogQue.front().num);
dogQue.pop();
}
else{
printf("%d ",catQue.front().num);
catQue.pop();
}
}
else if(type == 1){
// 领养狗
if(dogQue.empty()){
continue;
}
printf("%d ",dogQue.front().num);
dogQue.pop();
}
else{
// 领养猫
if(catQue.empty()){
continue;
}
printf("%d ",catQue.front().num);
catQue.pop();
}
}
}
printf("\n");
}