零散的笔记

高精度

输入输出格式

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;
}
posted @ 2021-04-15 22:28  VJJJJJJ  阅读(100)  评论(0编辑  收藏  举报