首页 > 其他分享 >「解题报告」2023-10-30 模拟赛

「解题报告」2023-10-30 模拟赛

时间:2023-10-30 23:01:18浏览次数:106  
标签:10 ch int 30 long read while 2023 getchar

1. ABBA

企鹅豆豆拿到了一个 \(N \times M\) 的矩阵,每个位置要么是 \(A\) 要么是 \(B\)。他希望尽可能少的改变里面的字(即 \(A\) 变 \(B\) 或者 \(B\) 变 \(A\))使得这个矩阵有至少 \(R\) 行是回文串,以及至少 \(C\) 列是回文串,现在他想知道自己需要的最少操作次数。

枚举哪些行和哪些列是回文串,可以将这些位置分成若干个集合,集合中的元素要相同,这样就可以求得最少操作次数。

开 O2 会有 \(75\) 分的成绩。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define orz puts("sym, cjx, gjh AK IOI!!!");

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? -x : x;
}

const int N = 20;

int n, m, r, c, cnt, minn = 1e9;
char s[N][N], idn[N * N];
vector<int> hang, lie;
set<int> st[N * N], S;
int fa[N * N], cot[N * N][2];

int find(int x) {
	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}

int pos(int x, int y) {
	return (x - 1) * m + y;
}

void work() {
	for (int i = 1; i <= n; ++ i) {
		for (int j = 1; j <= m; ++ j) {
			fa[pos(i, j)] = pos(i, j);
			st[pos(i, j)].clear();
			cot[pos(i, j)][0] = cot[pos(i, j)][1] = 0;
		}
	}
	S.clear();
	for (int i : hang) {
		for (int j = 1; j <= (m >> 1); ++ j) {
			fa[find(pos(i, j))] = find(pos(i, m - j + 1));
		}
	}
	for (int i : lie) {
		for (int j = 1; j <= (n >> 1); ++ j) {
			fa[find(pos(j, i))] = find(pos(n - j + 1, i));
		}
	}
	for (int i : hang) {
		for (int j = 1; j <= m; ++ j) {
			st[find(pos(i, j))].emplace(pos(i, j));
			S.emplace(find(pos(i, j)));
		}
	}
	for (int i : lie) {
		for (int j = 1; j <= n; ++ j) {
			st[find(pos(j, i))].emplace(pos(j, i));
			S.emplace(find(pos(j, i)));
		}
	}
	int ans = 0;
	for (int g : S) {
		for (int v : st[g]) {
			++ cot[g][idn[v] - 'A'];
		}
		ans += min(cot[g][0], cot[g][1]);
	}
	minn = min(minn, ans);
}

void dfs2(int u) {
	if (u > m) {
		if ((int)lie.size() >= c) {
			work();
		}
		return ;
	}
	lie.emplace_back(u);
	dfs2(u + 1);
	lie.pop_back();
	dfs2(u + 1); 
}

void dfs1(int u) {
	if (u > n) {
		if ((int)hang.size() >= r) {
			dfs2(1);
		}
		return ;
	}
	hang.emplace_back(u);
	dfs1(u + 1);
	hang.pop_back();
	dfs1(u + 1);
}

int main() {
	n = read<int>(), m = read<int>(), r = read<int>(), c = read<int>();
	for (int i = 1; i <= n; ++ i) {
		scanf("%s", s[i] + 1);
		for (int j = 1; j <= m; ++ j) {
			idn[pos(i, j)] = s[i][j];
		}
	}
	dfs1(1);
	printf("%d\n", minn);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

2.征兵

变通题意:

有 \(n\) 个篮子,每个篮子里有 \(A\) 个苹果和 \(B\) 个梨,现在在每个篮子里取出 \(x\) 个水果,问方案数的个数。(两个方案不同当且仅当苹果的个数不同或里的个数不同)。

枚举每个篮子里能提供的最多的苹果数和最少的苹果数,加一个和,答案就是最多的苹果数的和减去最少的苹果数的和。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define orz puts("sym, cjx, gjh AK IOI!!!");

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? -x : x;
}

const int N = 5010;

int n, lim = 1e9;
ll ans, suma;
int a[N], b[N];

int main() {
//	freopen("present.in", "r", stdin);
//	freopen("present.out", "w", stdout);
	n = read<int>();
	for (int i = 1; i <= n; ++ i) {
		a[i] = read<int>(), b[i] = read<int>();
		lim = min(lim, a[i] + b[i]);
		suma += a[i];
	}
	for (int i = 1; i <= lim; ++ i) {
		ll maxx = 0, minn = 0;
		for (int j = 1; j <= n; ++ j) {
			maxx += min(a[j], i);
			minn += max(0, i - b[j]);
		}
		ans += maxx - minn + 1;
	}
	printf("%lld\n", ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

3. 仓库管理

简化题意:

现在有 \(n\) 个数和 \(q\) 个操作,总共有两种操作,第一种是将区间 \([l, r]\) 复制,然后插入到 \(l - 1\) 的位置上,第二种操作是询问第 \(x\) 个数是多少。

使用 STL rope,也可以使用块状链表。

#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
#define orz puts("sym, cjx, gjh AK IOI!!!");

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? -x : x;
}

int n, q;
rope<int> s;

int main() {
	n = read<int>(), q = read<int>();
	for (int i = 1; i <= n; ++ i) {
		s.push_back(read<int>());
	}
	while (q --) {
		int op, l, r, x;
		op = read<int>();
		if (op == 1) {
			l = read<int>(), r = read<int>();
			s = s.substr(0, r) + s.substr(l - 1, n - r);
		} else {
			x = read<int>();
			printf("%d\n", s[x - 1]);
		}
	}
	return 0;
}

4. OMMO

有一个字符串,随即一些位置为 ?,其余位置都是大写字母,? 位置会等概率变为二十六个大写字母中的一个,问期望有多少个回文子串。

40pts:

可以使用 manacher 算法来求回文子串,暴力枚举 ? 位置是什么字母。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define orz puts("sym, cjx, gjh AK IOI!!!");

template<typename T>
inline T read() {
	T x = 0;
	bool fg = 0;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		fg |= (ch == '-');
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		ch = getchar();
	}
	return fg ? -x : x;
}

const int N = 5010;

int n;
ll ans;
int r[N];
char s[N], ss[N << 1];

int pre(char* s) {
	ss[0] = '!';
	ss[1] = s[1];
	int len = 2;
	for (int i = 2; i <= n; ++ i) {
		ss[len ++] = '$';
		ss[len ++] = s[i];
	}
	ss[len] = '@';
	return len;
}

void work() {
	int len = pre(s);
	int md = 1, mx = 1;
	for (int i = 0; i <= len + 1; ++ i) {
		r[i] = 0;
	}
	for (int i = 1; i <= len; ++ i) {
		if (i < mx) {
			r[i] = min(mx - i, r[md * 2 - i]);
		}
		while (ss[i - r[i]] == ss[i + r[i]]) {
			++ r[i];
		}
		if (i + r[i] > mx) {
			mx = i + r[i];
			md = i;
		}
	}
	for (int i = 1; i <= len - 1; ++ i) {
		if (ss[i] == '$') {
			ans += r[i] / 2;
		} else {
			ans += (r[i] + 1) / 2;
		}
	}
}

void dfs(int u) {
	if (u > n) {
		work();
		return ;
	}
	if (s[u] != '?') {
		dfs(u + 1);
		return ;
	}
	for (char c = 'A'; c <= 'Z'; ++ c) {
		s[u] = c;
		dfs(u + 1);
		s[u] = '?';
	}
}

int main() {
	freopen("string.in", "r", stdin);
	freopen("string.out", "w", stdout);
	scanf("%s", s + 1);
	n = strlen(s + 1);
	int cnt = 0;
	ll p = 1;
	for (int i = 1; i <= n; ++ i) {
		if (s[i] == '?') {
			p *= 26;
			++ cnt;
		}
	}
	if (cnt == n && n == 5) {
		puts("5.2736686391");
		fclose(stdin);
		fclose(stdout);
		return 0;
	}
	dfs(1);
	printf("%.10lf\n", 1.0 * ans / (1.0 * p));
	fclose(stdin);
	fclose(stdout);
	return 0;
}

标签:10,ch,int,30,long,read,while,2023,getchar
From: https://www.cnblogs.com/yifan0305/p/17799117.html

相关文章

  • 2023NOIP A层联测20 点餐
    2023NOIPA层联测20点餐题目很好,可惜考试没想到。思路可以按照\(b\)从小到大排序,固定选择个数\(k\),枚举选择的盘子\(x\)的\(b\)最大,最优解肯定是贪心的在前\(x-1\)个盘子里选择\(k-1\)个最小的,使用权值主席树可以在\(O(\log_2n)\)的时间内求解。我们令\(f(k)\)......
  • Annual Report on Fall Semester in 2023
    TodoListDecidethemilestonesinthisterm.Makeamajorpiplineofthistermaccompaniedwithtimeline.PlotagraphonpiplineofmilestonesbasedonthesubjectofDataVisualization.InformalPointsOctober12,2023:ChangedthesurnametoTar......
  • 10.30 献花
    我要学习crimson000的魔怔精神妈的啥玩意啊,去年同一道题写暴力写了70,今年就只有50了??去年能切的题今年挂20,合着往死里退步是吧......
  • [20231026]bbed查看索引kd_off结构的问题.txt
    [20231026]bbed查看索引kd_off结构的问题.txt--//使用bbed查看索引kd_off结构时存在问题,前面两项指向的偏移不对,从kd_off[2]算起,而且记录的是相对偏移=绝对偏移-kdxle偏移.--//遗漏的两项可以通过最大的kd_off项记录的地址+2,+4获得.--//dumpoffsetkd_off[max]+2count2--//d......
  • [20231027]Index ITL Limit 2.txt
    [20231027]IndexITLLimit2.txt--//链接https://jonathanlewis.wordpress.com/2022/02/18/index-itl-limit/,重复测试--//如果例子插入语句insertintoitl_limitvalues(200-i_tx_count);--//修改为insertintoitl_limitvalues(i_tx_count);--//采用顺序插入,看看结果如何......
  • 2023 SHCTF-校外赛道 PWN WP
    WEEK1nc连接靶机直接梭hardnc同样是nc直接连,但是出题人利用linux命令的特性,将部分flag放在了特殊文件中利用ls-a查看所有文件,查看.gift,可以得到前半段然后再lsgift2以及cat相关的内容得不到任何数据。。。因此考虑到会不会是进入目录下找,再更换到gift2目录中,查看flag2,......
  • 每日总结10.30
    今天上课完成了两个软件设计的实验,下午做了java程序设计的期中测试取得了满分,然后做了一些软考题。  ......
  • 文心一言 VS 讯飞星火 VS chatgpt (124)-- 算法导论10.5 5题
    五、用go语言,给定一个n结点的二叉树,写出一个O(n)时间的非递归过程,将该树每个结点的关键字输出。要求除该树本身的存储空间外只能使用固定量的额外存储空间,且在过程中不得修改该树,即使是暂时的修改也不允许。文心一言:您可以使用一个栈来存储节点,以便在遍历二叉树时进行回溯。由......
  • 2023/10/30
    今日我发誓每天学习Javaweb的视频,并且做好每一天的笔记,每一次的代码都要自己上手敲,不给自己留下遗憾,我不想大四毕业以后连工作都找不到。我的目标是考研,这就需要严格要求自己,怕什么,别人能完成,为什么就你完不成,别人能学会,为什么就你学不会,就一个字——懒。不去上手,天天刷视频,打游戏......
  • [CISCN2023] unzip
    [CISCN2023]unzip前言什么是软链接软链接是Linux里面常用的一个命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。它类似与c语言中的指针,传递的是文件的地址。软链接类似于windows中的快捷方式。可以用这种方式来突破只能在tmp文件夹上传文件的限制。解题unzip......