零散的笔记
高精度
输入输出格式
cin >> a >> b;
for(int i = a.size()-1; i >= 0; i--) A.push_back(a[i] - '0'); //输入并倒序存储
for(int i = b.size()-1; i >= 0; i--) B.push_back(b[i] - '0');
for(int i = C.size()-1; i >= 0; i--) printf("%d",C[i]); //输出
加法
vector<int> add(vector<int> &A, vector<int> &B){
vector<int> C;
if(A.size() < B.size()) return add(B, A);
int t = 0;
for(int i = 0; i < A.size(); i++){
t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if(t) C.push_back(1);
return C;
}
减法
vector<int> sub(vector<int> &A, vector<int> &B){
vector<int> C; //此时A > B,所以应该先写个cmp函数比较A、B大小
for(int i = 0, t = 0 ; i < A.size(); i++){
t = A[i] - t;
if(i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if(t >= 0) t = 0;
else t = 1;
}
while(C.size() > 1 && C.back() == 0) C.pop_back(); //弹出前导0
return C;
}
高精度A×低精度b
vector<int> mul(vector<int> A, int b ){
vector<int> C;
int t = 0;
for(int i = 0; i < A.size(); i++){
t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
if(t > 0) C.push_back(t); //处理最前一位
while(C.size() > 1 && C.back() == 0) C.pop_back();
//弹出前导0,如0乘以250
return C;
}
高精度A÷低精度b
vector<int> div(vector<int> &A, int b, int &r) //题目要输出余数,所以传入r的地址直接修改r
{
vector<int> C;
r = 0;
for (int i = A.size() - 1; i >= 0; i -- )
{
r = r * 10 + A[i];
C.push_back(r / b);
r %= b;
}
reverse(C.begin(), C.end()); //让C的结果逆序,方便去除前导0
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
qsort函数 int cmp(const void *pa, const void *pb)
数组的排序(从小到大)
int cmp(const void *pa, const void *pb){//头文件#inclide<stdlib.h>
int *a = (int *)pa;
int *b = (int *)pb;
return *a - *b;
}
依据结构体中的某个成员来排序
int cmp(const void *pa, const void *pb){
Student *a = (Student *)pa;
Student *b = (Student *)pb;
return a->id - b->id;
}
链表
建立动态链表
#define LEN sizeof(struct student)
struct student
{
long num;
float score;
struct student *next;
};
(struct student *)malloc(LEN) //注意每次要读取数据的时候都要申请一个空间!
遍历链表
for(p = head; p; p = p -> next)
删除结点
if(p1->num==d){ //删除结点
if(p1==head) head=p1->next;
else p2->next=p1->next; //p2在p1前面一个位置
free(p1); //释放所删除结点的空间
}
将数字插到链表里
struct node *insert(struct node *head, int i){ //i是插入的位置,表示插在第i-1个后面
struct node *p,*q;
p=head;
q=(struct student *)malloc(LEN); //要读入数据,所以需要申请空间
scanf("%ld,%f",&q->num,&q->score);
if(i==1){q->=head; head=q;} //插到头结点
else{
for(j=1;j<i-1;j++){ //让p2等于i-2个位置的next,即访问第i-1位
p=p->next;
}
q->next=p->next; //插入操作
p->next=q;
}
return(head);
}
逆波兰表达式
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
数学知识
辗转相除法
int gcd(int a, int b){
if(a < b) return gcd(b, a);
return a % b? gcd(b, a % b) : b;
}
欧拉函数
int eular(int x){
int res = x;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0){
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
if (x > 1) res = res / x * (x - 1); //没除尽,还有其他的质数
return res;
}
dfs与bfs
约瑟夫递归环
int ysfdg ( int sum, intvalue, intn)
{
if ( n == 1 )
return ( sum + value - 1 ) %sum;
else
return ( ysfdg ( sum-1, value,n-1 ) +value ) %sum;
}
//sum指的是总人数,value指的是每次最大报到的数值,n是第n次,该函数每次可以求出第n次扔海里的人的编号
dfs求电梯问题
#include<bits/stdc++.h>
using namespace std;
const int N = 210;
int n, A, B, Min = 99999999;
int a[N],flag[N] = {0}; //flag记录这个楼层有没有到达过
void dfs(int index, int cnt){
if(index == B){
Min = min(Min, cnt);
}
else if(cnt < Min){
flag[index] = 1;
if(index + a[index] <= n && flag[index + a[index]] == 0) dfs(index + a[index], cnt + 1); //上升
if(index - a[index] >= 1 && flag[index + a[index]] == 0) dfs(index - a[index], cnt + 1); //下降
flag[index] = 0; //回溯
}
return;
}
int main(){
cin >> n >> A >> B;
for(int i = 1; i <= n; i ++){
cin >> a[i];
}
dfs(A,0);
if(Min == 99999999) cout << -1;
else cout << Min;
return 0;
}
广度优先搜索思想
1、对于初始状态入队,设置初始状态为已访问
2、如果队列不为空时,出队队头元素,否则跳到第5步
3、检查出队的元素是否为最终解,如果是则跳到第5步。
4、对于出队的元素,检查所有相邻状态,如果有效并且未访问,则将
所有有效的相邻状态进行入队,并且设置这些状态为已访问,然后
跳到第2步重复执行
5、检查最后出队的元素是否为最终解,如果是输出结果,否则说明无解
q.push()
入队操作 q.front()
取队头元素
q.pop()
队头元素出队 q.size()
获取队列的元素个数
q.empty()
判断队列是否为空,为空返回true,不为空返回false
bfs求电梯问题
typedef struct {
int floor; //当前所处的楼层编号
int pushcount; //到达该楼层所经历的步数(按按钮次数)
} QElement;
queue<QElement> q; //定义元素类型为QElement的队列q
int n,a,b;
int s[1000]; //数组s记录每个楼层按按钮后能上下的楼层数
int t[1000]={0}; //数组t记录各个楼层是否已经到达过(已访问过)
int main()
{
QElement e1,e2;
int i;
cin >> n >> a >> b;
for (i=1; i<=n; i++) cin >> s[i];
e1.floor=a;
e1.pushcount=0;
q.push(e1); //初始状态入队:当前楼层为a,按按钮次数为0
t[a]=1; //记录当前楼层已访问过
while (!q.empty()) //当队列不为空时,继续宽度优先搜索
{
e2=q.front(); //获取队头元素
q.pop(); //队头元素出队(注意:c++的队列模板类中,获取队头元素并不会将该元素从队列中删除,需要使用pop函数删除该元素)
if (e2.floor==b) break; //检查当前状态的楼层编号是否为b,是则说明已经找到最终解,跳出循环
i=e2.floor+s[e2.floor]; //按向上按钮后能够到达的楼层
if (i<=n && t[i]==0) //如果按向上按钮能到达的楼层有效并且未访问过该楼层
{
e1.floor=i;
e1.pushcount=e2.pushcount+1;
q.push(e1);
t[i]=1; //设该楼层为已访问过
}
i=e2.floor-s[e2.floor]; //按向下按钮后能够到达的楼层
if (i>=1 && t[i]==0) //如果按向下按钮能到达的楼层有效并且未访问过该楼层
{
e1.floor=i;
e1.pushcount=e2.pushcount+1;
q.push(e1);
t[i]=1; //设该楼层为已访问过
}
}
//如果当前楼层为b,输出按按钮次数,否则无解(输出-1)
if (e2.floor==b) cout << e2.pushcount;
else cout << -1;
}
军训
某部队进行新兵队列训练,将新兵从1开始按顺序依次编号,并排成一行横队。训练的规则如下:从头开始1至2报数,凡报到2的新兵出列,剩下的新兵向小序号方向靠拢;再从头开始进行1至3报数,凡报到3的新兵出列,剩下的向小序号方向靠拢;继续从头开始进行1至2报数。。。;如此这样一直进行,直到剩下的人数不超过3人为止。
#include<stdio.h>
int a[2][5001];
int main(){
int t,n,cur,size;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
cur=0;
for(int i=1;i<=n;i++){
a[cur][i]=i;
}
while(n>3){
size=0;
for(int i=1;i<=n;i++){
if(i%(cur+2)==0){
continue;
}
else{
a[(cur+1)%2][++size]=a[cur][i];
}
}
cur=(cur+1)%2;
n=size;
}
for(int i=1;i<=n;i++){
printf("%d%c",a[cur][i],i==n?'\n':' ');
}
}
}
可怕的素质
#include<stdio.h>
#include<stdlib.h>
#define len sizeof(struct People)
struct People{
int index;
int x;
struct People *next;
};
struct People *insert(struct People *head, struct People *p){
struct People *q1, *q2;
q2 = head;
q1 = head->next;
if(p->x == 0){
p->next = q2;
head = p;
}
else{
for(struct People *q = head; q != NULL; q = q->next){
if(q->index == p->x){
p->next = q->next; //注意顺序
q->next = p;
break;
}
}
//或者
/*for(;q2 != NULL;q2 = q1, q1 = q1->next){
if(q2->index == p->x){
q2->next = p;
p->next = q1;
break;
}
}*/
}
return head;
}
int main(){
int n,x;
struct People *head, *p1, *p2;
head = NULL;
scanf("%d",&n);
p1 = (struct People *)malloc(len);
scanf("%d", &p1->x);
p1->index = 1;
head = p1;
head->next = NULL;
for(int i = 2; i <= n; i ++){
p1 = (struct People *)malloc(len);
scanf("%d",&p1->x);
p1->index = i;
head = insert(head, p1);
}
for(struct People *pri = head; pri; pri = pri->next){
printf("%d%c",pri->index,pri->next == NULL?'\n':' ');
}
return 0;
}