2023“钉耙编程”中国大学生算法设计超级联赛(3)

这篇具有很好参考价值的文章主要介绍了2023“钉耙编程”中国大学生算法设计超级联赛(3)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1005.Out of Control

题意:

有n个数\(x_1,x_2,...,x_n\),在其中选k个数依次放入栈中。如果当前放入栈中的数\(x_i\)小于栈顶的数,则向栈中放入与先前的栈顶相同的数而不是\(x_i\)。求对于每个k对应的方案数。

分析:

先排序离散化,然后考虑dp。
状态定义: f[i][j]表示长度为i且最后一个数是j的方案数。
状态转移:
f[i][j] = \(\sum_{t = 1}^jf[i - 1][t]\)
答案:
长度为 i的栈由长度为i - 1的栈转移过来, 且长度为i - 1的栈最后一位要小于等于j。那么对于长度为i的这类问题的答案即\(\sum_{j = i + 1}^nf[i][j]\),条件就是小于等于j的数量必须要大于等于i

优化:
对于求f[i][j] = \(\sum_{t = 1}^jf[i - 1][t]\)
f[i][1] = f[i - 1][1]
f[i][2] = f[i - 1][1] + f[i - 1][2] = f[i][1] + f[i - 1][2]
f[i][3] = f[i - 1][1] + f[i - 1][2] + f[i - 1][3] = f[i][2] + f[i - 1][3]
因此:
f[i][j] = f[i][j - 1] + f[i - 1][j]
\(\Rightarrow\) f[j] = f[j - 1] + f[j] \(\Rightarrow\) f[j] += f[j - 1]

因此f[n]即为答案。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 3010, mod = 1e9 + 7;

LL f[N];
int a[N];

int main() {
	std::ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	
	int t;
	cin >> t;
	
	while (t --) {
		int n;
		cin >> n;
		
		for (int i = 1; i <= n; i ++) {
			cin >> a[i];
		}
		
		sort(a + 1, a + 1 + n);
		
		for (int i = 1; i <= n; i ++) {
			if (a[i] > a[i - 1])
				f[i] = f[i - 1] + 1;
			else
				f[i] = f[i - 1];
		}
		
		cout << f[n] << "\n";
		for (int i = 2; i <= n; i ++) {
			for (int j = i + 1; j <= n; j ++) {
				if (a[j] > a[j - 1])
					f[j] = (f[j] + f[j - 1]) % mod;
				else
					f[j] = f[j - 1]; 
			}
			
			cout << f[n] << "\n"; 
		}
	}
	
	return 0;
}

1011.8-bit Zoom

题意:

将 n × n 的矩阵放大为原来的 z% 倍,不行则输出 error

分析:

按题意模拟一下即可

代码:

#include <bits/stdc++.h>
using namespace std;

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t, n, z;
    char g[55][55];
    cin >> t;
    while (t--) {
        cin >> n >> z;
        for (int i = 0; i < n; i++) {
            cin >> g[i];
        }
        if ((n * z) % 100 != 0) {
            cout << "error" << endl;
        }
        else if ((1 * z) % 100 == 0) {
            int p = z / 100;
            for (int i = 0; i < n * z / 100; i++) {
                for (int j = 0; j < n * z / 100; j++) {
                    cout << g[i / p][j / p];
                }
                cout << endl;
            }
        }
        else if (2 * z % 100 == 0) { // z == 150
            bool flag = true;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j += 2) {
                    if (g[i][j] != g[i][j + 1] || g[j][i] != g[j + 1][i]) {
                        flag = false;
                        break;
                    }
                }
                if (!flag) break;
            }
            if (flag) {
                for (int i = 0; i < n * z / 100; i++) {
                    for (int j = 0; j < n * z / 100; j++) {
                        cout << g[i / 3 * 2][j / 3 * 2];
                    }
                    cout << endl;
                }
            }
            else {
                cout << "error" << endl;
            }
        }
        else { // z = 125, z = 175;
            bool flag = true;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j += 4) {
                    for (int k = j; k < j + 2; k++) {
                        if (g[i][k] != g[i][k + 1] || g[k][i] != g[k + 1][i]) {
                            flag = false;
                            break;
                        }
                    }
                    if (!flag) break;
                }
                if (!flag) break;
            }
            if (flag) {
                int p = z * 4 / 100;
                for (int i = 0; i < n * z / 100; i++) {
                    for (int j = 0; j < n * z / 100; j++) {
                        cout << g[i / p * 4][j / p * 4];
                    }
                    cout << endl;
                }
            }
            else {
                cout << "error" << endl;
            }
        }
    }

    return 0;
}

1012.Noblesse Code

题意:

给定n个模板二元组(\(a_i, b_i\)),有q次询问,每次给你一个二元组(A,B),问能通过若干次操作得到的模板二元组的数量。每次操作可以让(A,B)变成(A+B,B)或者(A,A+B)。

分析:

(A,B)的正向操作有两种,但它的逆向操作有且只有一种。
若A > B,则一定由(A - B, B)得来;
若A < B,则一定由(A, B - A)得来;
若A = B,则一定由(A, B)得来。
把这种关系用二叉树来表示,(A, B)的根节点是(gcd(A, B), gcd(A, B))。若(A, B)能通过一系列操作得到(a, b)则,(A,B)到根节点的路径必然是(a, b)到根节点路径的前缀。一种暴力的做法就是把路径求出来,然后计算能够匹配的数量。但这个路径会很长,考虑如何优化。
对于一个二元组(a, b),假设a > b,我们观察路径:(a, b)-> (a - b, b)->(a - 2b, b), ... , (a % b, b), (a % b, b - (a % b)), (a % b, b - 2(a % b)), ... , (a % b, b % (a % b))...可以发现我们可以将那些具有相同操作的点归为一类,只考虑起点和拐点,因此我们可以进行路径压缩,一种压缩路径的方式是将拐点映射到一个起点的有序集合(A > B下的映射关系保留横坐标即可)。这样一来,我们就可以预处理n个二元组,对于每次询问,我们只需二分查找(A, B)逆向对应的拐点映射的有序集合即可得到答案。
整理一下:
1.预处理映射:
①映射1:a > b, (a % b, b) \(\rightarrow\) set(x)。set(x)是起点横坐标的有序集合。
②映射2:a < b, (a, b % a) \(\rightarrow\) set(y)。set(y)是起点纵坐标的有序集合。
③映射3:a = b, a \(\rightarrow\) cnt(a)。cnt(a)是起点横坐标a出现的次数。
2.对于每次询问(A, B):
①若A > B,在映射1中二分查找key = (A % B, B)对应的set(x), 统计x >= A的数量。
②若A < B,在映射2中二分查找key = (A, B % A)对应的set(y), 统计y >= B的数量。
③若A = B,在映射1中二分查找key = (0, B)对应的set(x),累加答案,在映射2中二分查找key = (A,0)对应的set(y),累加答案,在映射3中累加key = a对应的cnt(a)。文章来源地址https://www.toymoban.com/news/detail-692516.html

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> PLL;
map<PLL, vector<LL>> mp1, mp2;
map<LL, LL> mp3;

int main() {
	std::ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	
	int t;
	cin >> t;
	
	while (t --) {
		mp1.clear();
		mp2.clear();
		mp3.clear();
		
		int n, m;
		cin >> n >> m;
		
		for (int i = 0; i < n; i ++) {
			LL a, b;
			cin >> a >> b;
			
			if (a == b) {
				mp3[a] ++;
			} else {
				while (a && b) {
					if (a > b) {
						mp1[{a % b, b}].push_back(a);
						a = a % b;
					} else {
						mp2[{a, b % a}].push_back(b);
						b = b % a;
					}
				} 
			}
			
		}
		
		for (auto &x : mp1) {
			sort(x.second.begin(), x.second.end());
		}
		for (auto &x : mp2) {
			sort(x.second.begin(), x.second.end());
		}
			
		while (m --) {
			LL ans = 0;
				
			LL a, b;
			cin >> a >> b;
				
			if (a > b) {
				auto &v = mp1[{a % b, b}];
				ans += v.end() - lower_bound(v.begin(), v.end(), a);
			} else if (a < b) {
				auto &v = mp2[{a, b % a}];
				ans += v.end() - lower_bound(v.begin(), v.end(), b);
			} else {
				auto &v1 = mp1[{0, b}];
				auto &v2 = mp2[{a, 0}];
					
				ans += v1.end() - lower_bound(v1.begin(), v1.end(), a);
				ans += v2.end() - lower_bound(v2.begin(), v2.end(), b);
				ans += mp3[a];
			}
				
			cout << ans << "\n";
		}
	} 
	
	return 0;
}

到了这里,关于2023“钉耙编程”中国大学生算法设计超级联赛(3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(4)

    1003 Simple Set Problem 双指针的思想,双端队列 先从小到大排个序 一个一个放到双端队列里,一边放一边维护集合个数为k个 利用滑动窗口,当滑动窗口中集合个数为k时,只需算出滑动窗口最后一个数减去第一个数,然后每次取min就行了 AC代码:  1006 PSO  两两组合 期望=所有组合的边

    2024年02月15日
    浏览(20)
  • 2023“钉耙编程”中国大学生算法设计超级联赛(1)Hide-And-Seek Game

    2023“钉耙编程”中国大学生算法设计超级联赛(1)Hide-And-Seek Game 题目大意 有一棵有 n n n 个节点的树,小 S S S 和小 R R R 在树上各有一条链。小 S S S 的链的起点为 S a S_a S a ​ ,终点为 T a T_a T a ​ ;小 R R R 的链起点为 S b S_b S b ​ ,终点为 T b T_b T b ​ 。 小 S S S 和小 R R

    2024年02月16日
    浏览(24)
  • 2023年度第四届全国大学生算法设计与编程挑战赛(春季赛)

     A 题目描述        有一个长为 n (1le n le 1000)n (1≤n≤1000) 的序列,序列上的元素两两不同。你需要用最少的操作步数翻转这个序列。        每次操作你需要给出三个数 i,j,k(1le ile j k le n)i,j,k(1≤i≤jk≤n),交换序列中下标属于 [i,j][i,j] 的元素与下标属于 [j+1,k][j+

    2024年02月08日
    浏览(45)
  • 2023年天府杯全国大学生数学建模竞赛B题中国环境问题的治理解题全过程

       问题背景:    随着经济的快速发展和人口的持续增长,中国的环境问题已经成为了一个急需解决的重要问题。这些环境问题不仅对人们的健康和生活质量产生了巨大的影响,还对生态系统和生态平衡造成了极大的破坏。近年来,中国政府积极推动环保事业的发展,通

    2024年02月08日
    浏览(17)
  • 2023年四川大学生程序设计竞赛-K.倒转乾坤

    Cuber QQ 现在手上有两个圆环,其中小圆环的直径是 d,大圆环的直径是 2d 。他将小圆环放在大圆环内, 并让小圆环紧贴大圆环内壁进行无滑动的滚动。   Cuber QQ 总是喜欢动态的美,他在小圆环上等间隔地标记了 n 个点,他想知道在小圆环贴着大圆环运动一周后,他所

    2024年02月16日
    浏览(31)
  • 【电子设计大赛】2023 年全国大学生电子设计竞赛 仪器和主要元器件清单

    1. 仪器设备清单 直流稳压电源(具有恒流/恒压模式自动切换功能,0~30V/3A,双路) 数字示波器(100MHz, 双通道) 函数发生器(50 MHz,双通道) 射频信号源(500MHz,-100dBm~0dBm,具有射频输出开关功能) 矢量网络分析仪(1GHz) 频谱分析仪(1GHz) 频率计(500MHz) 功率分析仪

    2024年02月15日
    浏览(25)
  • 2023 年第五届河南省 CCPC 大学生程序设计竞赛

    Problem A. 小水獭游河南 ∣ a ∣ ≤ ∣ Σ ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O ( ∣ Σ ∣ ∣ s ∣ ) 。 |a| ≤ |Σ| = 26,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O(|Σ||s|)。 ∣ a ∣ ≤ ∣Σ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复

    2024年02月03日
    浏览(49)
  • 2023年第十五届“中国电机工程学会杯”全国大学生电工数学建模竞赛题目 A题:电采暖负荷参与电力系统功率调节的技术经济分析

    建设以新能源为主体的新型电力系统是应对全球气候变化挑战的重要举措。高比例新能源接入导致电力系统调节能力稀缺,亟需开发新的调节资源,如火电深度调峰、建设抽水蓄能电站、配置储能和挖掘负荷中的调节能力等。现代电力负荷中含有较大比重的温控型负荷(如空

    2024年02月06日
    浏览(24)
  • 【毕业设计】基于springboot的大学生综合素质测评系统——2023最新推荐

    【毕业设计】基于springboot大学生综测管理系统 🥇 个人主页 :@MIKE笔记 🥈 文章专栏 :毕业设计源码合集 ⛄ 联系博主: wx: mikenote 项目名 文章地址 💹下载 基于springboot的 大学生综合素质测评管理系统 http://t.csdn.cn/smVjL v1.0 // v2.0 基于springboot + vue 微信小程序文创平台商城

    2024年02月06日
    浏览(22)
  • 第五届湖北省大学生程序设计竞赛(HBCPC 2023)vp赛后补题

    思路: 数位dp,如果我们暴力的计算的状态的话,显然就是记录每个数字出现几次。但是显然这样难以发挥数位dp的记忆化功效,因为只有出现次数相同,你是什么数字,实际是无所谓的。所以我们尝试记录每个出现次数有多少个数字 尝试打表发现,结果只有1477种 所以,对

    2024年02月07日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包