• 一些洛谷题单里的题目


    1.洛谷 - P1012 拼数
    这个题吧,一开始想的是用转字符串排序,但是注意两个数字42和426,另一组数是42和421,他们经过字符串排序之后的结果都是一样的426在42前面没啥说的,但是421不能在42前头,然后就换个思路被,可以这样做:

    sort(dp.begin(), dp.begin() + n, [](string &a1, string &a2) {
    		return (a1+a2)>(a2+a1); });
    
    
    • 1
    • 2
    • 3

    这样的排序之后就可以了
    2.洛谷 - P1541 乌龟棋
    对于这个题,我对学校的那个状态对还是什么玩意的印象特别深刻,主要是,嗯,会超内存,又没法往下剪枝,所以可以用这个方法:
    由于他只有4张卡片,所以可以设置一个四维数组,嗯,这是之前看别人题解想到的,还是得自己想出来才有意义啊,这已经是一个月之前的事了,
    状态转移方程如下:

    dp[a-1][b][c][d]=max(dp[a][b][c][d]+graph[r],dp[a-1][b][c][d]);
    
    • 1

    嗯,,就这样了
    E - 国王游戏 洛谷 - P1080
    这个题也没啥难的
    就是这个大臣他的左边所有人的左手数字乘在一起然后再除以右手的数字,让这个值尽量小,怎么做?我们来看,我们考虑终止状态,这一堆人站在一起,国王一定要乘,那我就把所有人的左手数字全部都乘在一起(这是个定值),然后看最终结果,是不是就是这个定值除以最后那个人的左手数值,再除以右手的数值,让这个数最小,那就把最大的乘积放在后面不就行了吗》
    这个题难点不在这,问题是我能想到这个,我咋A掉,就要实现高精度乘法,额,,还有高精度除法,额,还有高精度加法,还有高精度比大小
    …我先放一个我没写完的吧,这个是用二进制的bitset做的,也参考了一些知乎上的,还没调试,还没过:

    #include
    #include
    using namespace std;
    #define max(a,b) (a>b)?a:b
    typedef bitset<12000> dz;
    dz a;
    dz b;
    dz operator +(dz a1,dz a2)
    {
    	return b.any() ? (a1^a2) + (a1&a2) << 1 : a1;
    }
    dz operator *(dz a1, dz a2)
    {
    	dz temp=a1;
    	dz base = 1;
    	while (a1 != 0)
    	{
    		if(a1[0])
    		a2 = a2 + base;
    		base = base << 1;
    	}
    	return a2;
    }
    bool operator<(dz a1, dz a2)
    {
    	for (int i = a1.size() - 1; i >= 0; i--)
    	{
    		if (a1[i] != a2[i])
    		{
    			return a1[i] < a2[i];
    		}
    	}
    }
    bool operator<=(dz a1, dz a2)
    {
    	if (a1 < a2)
    		return 1;
    	else
    	{
    		for (int i = 0; i < a1.size(); i++)
    		{
    			if (a1[i] != a2[i])
    				return 0;
    		}
    		return 1;
    	}
    }
    dz operator -(dz a1, dz a2)
    {
    	return a1 + (~a2 + 1);
    }
    dz operator /(dz a1, dz a2)
    {
    	int i = 0;
    	dz res;
    	while ((a2 << i) < a1)
    	{
    		i++;
    	}
    	for (; i >= 0; i--)
    	{
    		if ((a2<<i)<=a1)
    		{
    			res[i] = 1;
    			a1 = a1 - (a2 << i);
    		}
    	}
    	return res;
    }
    int main(void)
    {
    	dz res=1;
    	int n;
    	scanf_s("%d", &n);
    	int b,c;
    	scanf_s("%d%d", &b, &c);
    	res = c;
    	int max1 = -1;
    	for (int i = 0; i < n; i++)
    	{
    		scanf_s("%d%d", &b, &c);
    		res = res * b;
    		max1 = max(max1, b*c);
    	}
    	res = res / max1;
    	printf("%lld", res.to_ullong());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    还有这个:
    F - 地毯 洛谷 - P3397
    这个题嘛,就是用暴力应该会超时,不开O2应该过不了,然后我就用了线段树,他两个维度不是无关的,而是相关的,必须要用二维的线段树

    #include
    using namespace std; 
    const int length = 1e3 + 5;
    struct s
    {
    	int sum;
    	int add;
    };
    struct s tree[length << 3][length<<3];
     
    //奶奶的这是二维的线段树
    void update(struct s *tree, int L, int R, int l, int r, int cnt)
    {
    	if (l > R || r < L)return;
    	if (l >= L && r <= R)
    	{
    		tree[cnt].add += 1;
    		return;
    	}
    	int mid = (l + r) / 2;
    	update(tree, L, R, l, mid, cnt * 2);
    	update(tree, L, R, mid + 1, r, cnt * 2 + 1);
    }
    int query(struct s *tree, int L, int R, int l, int r, int cnt)
    {
    	if (l > R || r < L)return 0;
    	if (l >= L && r <= R)
    	{
    		return tree[cnt].sum+(r-l+1)*tree[cnt].add;
    	}
    	tree[cnt * 2].add += tree[cnt].add;
    	tree[cnt * 2 + 1].add += tree[cnt].add;
    	tree[cnt].add = 0;
    	int mid = (l + r) / 2;
    	int a=query(tree, L, R, l, mid, cnt * 2);
    	int b=query(tree, L, R, mid + 1, r, cnt * 2 + 1);
    	int suml = tree[cnt * 2].sum + (mid - l + 1)*tree[cnt * 2].add;
    	int sumr = tree[cnt * 2 + 1].sum + (r - mid)*tree[cnt * 2 + 1].add;
    	tree[cnt].sum = suml+sumr;
    	return a + b;
    }
    int main(void)
    {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 0; i < m; i++)
    	{
    		int x1, y1, x2, y2;
    		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    		for (int j = x1; j <= x2; j++)
    		{
    			update(tree[j], y1, y2, 1, n, 1);
    		}
    	}
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j <= n; j++)
    		{
    			int a = query(tree[i], j, j, 1, n, 1);
    			//int b = query(tree_lie, j, j, 1, n, 1);
    			printf("%d ", a );
    		}
    		printf("\n");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    好了,下午签了个到,也算没做大牢

  • 相关阅读:
    【LeetCode刷题(数据结构与算法)】:上下翻转二叉树
    通过Excel,生成sql,将A表数据插入B表
    【kubernetes篇】通过描述信息,理解Pod生命周期
    世上最全PETSC Linux安装攻略:天河新一代超算上PETSC安装,运行
    zookeeper安装教程(Windows)
    微服务项目实战-黑马头条(三):APP端文章详情
    交付实施工程师是做什么的?
    分析Python7个爬虫小案例(附源码)
    K8S常用命令
    数字孪生技术钢铁行业可视化管理平台
  • 原文地址:https://blog.csdn.net/weixin_52205764/article/details/128005993