#基础编程#一些函数整理

优先队列

 priority_queue < int > q;//从大到小
 priority_queue < int , vector < int > , greater < int > > q;//从小到大

sort递减

bool cmp(int a, int b)
{
    return a > b;
}

判断素数

bool IsPrimeNumber(int n)
{
	if(n <= 1)
		return false;
	for(int i = 2 ; i <= sqrt(n) ; i++)
	{
		if(n % i == 0)
			return false;
	}
	return true;
}

素数筛法

const int maxn = 101;//表长
int prime[maxn], pNum = 0;//prime数组存放所有素数,pNum为素数个数
bool p[maxn] = {0};//如果i为素数,则p[i]为false,否则为true
void Find_Prime()
{
	for(int i = 2; i < maxn; i++)
	{
		if(p[i] == false)//如果i是素数
		{
			prime[pNum++] = i;//把素数i存到prime数组中
			for(int j = i + 1; j < maxn; j+= i)
			{//筛去所有i的倍数
				p[j] = true;
			}
		}
	}
}

日期类

int isleap(int y)
{
    if((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
        return 1;
    else
        return 0;
}

int month[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}};

进制转换(除基取余)

int z[40], num = 0;
    do
    {
        z[num++] = y % q;
        y = y / q;
    }while(y != 0);

判断回文

bool judge(char str[])
{
    int len = strlen(str);
    for(int i = 0; i < len/2; i++)
    {
        if(str[i] != str[len - i - 1])
            return false;
    }
    return true;
}

区间贪心

struct interval
{
    int x, y;//开区间左右端点
}m[110];

bool cmp(interval a, interval b)
{
    if(a.x != b.x)
        return a.x > b.x;//先按左端点从大到小排序
    else
        return a.y < b.y;//左端点相同,按右端点从小到大排序
}

int main()
{
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n;
    int i;
    while(scanf("%d", &n) != EOF)
    {
        if(n == 0)
            break;
        for(i = 0; i < n; i++)
            scanf("%d %d", &m[i].x, &m[i].y);
        sort(m, m + n, cmp);//区间排序
		//ans记录不想交区间个数,last记录上一个被选中区间的左端点
        int ans = 1, last = m[0].x;
        for(i = 1; i < n; i++)
        {
            if(m[i].y <= last)//如果该区间右端点在last左边
            {
                last = m[i].x;//以m[i]作为新选中的区间
                ans++;//不相交区间个数加1
            }
        }
        printf("%d\n", ans);
    }
}

最大公约数

int gcd(int a, int b)
{
	if(b == 0)
		return a;
	else
		return gcd(b, a % b);
	//return !b ? a : gcd(b, a % b);//简洁写法
}

最小公倍数

int lcm(int a, int b)
{
	int d = gcd(a, b);
	return a / d * b;
}

分数的表示与化简

struct Fraction
{
	int up, down;
};

Fraction reduction(Fraction result)
{
	if(result.down < 0)
	{
		result.up = -result.up;
		result.down = -result.down;
	}
	if(result.up == 0)
		result.down = 1;
	else
	{
		int d = gcd(abs(result.up), abs(result.down));
		result.up /= d;
		result.down /= d;
	}
	return result;
}

大数运算

  • 加法
struct bign
{
	int d[1000];
	int len;
	bign()
	{
		memset(d, 0, sizeof(d));
		len = 0;
	}
};

bign change(char str[])//将整数转换为bign
{
	bign a;
	a.len = strlen(str);
	for(int i = 0; i < a.len; i++)
	{
		a.d[i] = str[a.len - i - 1] - '0';
	}
	return a;
}

//加法
//如果由一方是负的,可以再转换到数组时去掉符号,然后算减法
//如果都是负的,去掉符号算加法,最后加上负号
bign add(bign a, bign b)
{
	bign c;
	int carry = 0;//进位
	for(int i = 0; i < a.len || i < b.len; i++)
	{
		int tmp = a.d[i] + b.d[i] + carry;
		c.d[c.len++] = tmp % 10;
		carry = tmp / 10;
	}
	if(carry != 0)
		c.d[c.len++] = carry;
	return c;
}

//减法
//先比较两个数大小,如果被减数小于减数,交换变量,输出符号
bign sub(bign a, bign b)
{
	bign c;
	for(int i = 0; i < a.len || i < b.len; i++)
	{
		if(a.d[i] < b.d[i])//不够减
		{
			a.d[i + 1]--;
			a.d[i] += 10;
		}
		c.d[c.len++] = a.d[i] - b.d[i];
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0)
		c.len--;//去除最高位的0,同时至少保留一位最低位
	return c;
}

//乘法
//可以先记录正负号,取绝对值代入函数
bign multi(bign a, bign b)
{
	bign c;
	int carry = 0;//进位
	for(int i = 0; i < a.len; i++)
	{
		int tmp = a.d[i] * b + carry;
		c.d[c.len++] = tmp % 10;
		carry = tmp / 10;
	}
	while(carry != 0)
	{//乘法进位可能不止一位
		c.d[c.len++] = carry % 10;
		carry /= 10;
	}
	return c;
}

//除法
bign divide(bign a, int b, int& r)//r为余数
{
	bign c;
	c.len = a.len;//被除数的每一位和商的每一位是一一对应的,因此先令长度相等
	for(int i = a.len - 1; i >= 0; i--)
	{
		r = r * 10 + a.d[i];
		if(r < b)
			c.d[i] = 0;//不够除
		else
		{
			c.d[i] = r / b;
			r = r % b;
		}
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0)
	{//去除最高位的0,同时至少保留一位最低位
		c.len--;
	}
	return c;
}

Fibonacci

int fibo(int a)
{
    if(a<=2)
        return 1;
    else
        return fibo(a-1)+fibo(a-2);
}

BFS

void BFS(int s)
{
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		取出队首元素top;
		访问队首元素top;
		将队首元素出队;
		将top的下一层结点中未曾入队的结点全部入队,并设置为已入队;
	}
}

二叉树遍历

  • 先序遍历
void preorder(node* root)
{
	if(root == NULL)
		return;
	printf("%d\n", root->data);
	preorder(root->lchild);
	preorder(root->rchild);
}
  • 中序遍历
void inorder(node* root)
{
	if(root == NULL)
		return;
	inorder(root->lchild);
	printf("%d\n", root->data);
	inorder(root->rchild);
}
  • 后序遍历
void postorder(node* root)
{
	if(root == NULL)
		return;
	postorder(root->lchild);
	postorder(root->rchild);
	printf("%d\n", root->data);
}
  • 层次遍历
struct node
{
	int data;
	int layer;
	node* lchild;
	node* rchild;
};

void LayerOrder(node* root)
{
	queue<node*> q;
	root->layer = 1;
	q.push(root);
	while(!q.empty())
	{
		node* now = q.front();
		q.pop();
		printf("%d", now->data);
		if(now->lchild != NULL) 
		{
			now->lchild->layer = now->layer + 1;
			q.push(now->lchild);
		}
		if(now->rchild != NULL) 
		{
			now->rchild->layer  = now->layer + 1;
			q.push(now->rchild);
		}
	}
}

动态规划

//最大连续子序列和:找状态方程!
//a[i]为输入的数,dp[i]用于找子序列
dp[i] = max(a[i], dp[i-1] + a[i]);
//01背包问题
//w[i]为重量,c[i]为价值,V为容量
for(int i = 1; i <= n; i++)
{
	for(int v = w[i]; v <= V; v++)
		dp[i][v] = max(dp[i-1][v], dp[i-1][v-w[i]]+c[i]);
}

//进一步优化空间复杂度
//边界
for(v = 0; v <= V; v++)
	dp[v] = 0;
for(i = 1; i <= n; i++)
{
	for(int v= V; v >= w[i]; v--)
		dp[v] = max(dp[v], dp[v-w[i]]+c[i]);
}

//完全背包问题
//w[i]为重量,c[i]为价值,V为容量
for(int i = 1; i <= n; i++)
{
	for(int v = w[i]; v <= V; v++)
		dp[i][v] = max(dp[i-1][v], dp[i][v-w[i]]+c[i]);//唯一区别,第二个参数为dp[i]
}

//进一步优化空间复杂度
//边界
for(v = 0; v <= V; v++)
	dp[v] = 0;
for(i = 1; i <= n; i++)
{//区别:正向枚举
	for(int v = w[i]; v <= V; v++)
		dp[v] = max(dp[v], dp[v-w[i]]+c[i]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值