2022.9.13———HZOI【CSP-S模拟5】游寄

Preface

Rank38/43

30pts+0pts+30pts+0pts=60pts

分好低。。

T1 F, T2 S, T3 Y, T4 o

T1 F

mad场切题我又没切

枚举。没错,枚举。

但是我枚举的太多了,显然的枚举更少的思路我没发现。我真shab。

思路很简单,考虑到x一定是a_1和某个b_i的异或值,所以x的取值只有n种

然后就正常枚举正常判断就完了

T1
#include <iostream>
#include <algorithm>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 2005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
/*
	超 场切的题我没切
	这两天老这样
	这个题和赛时思路一样
	但是赛时sb了枚举了太多的x
*/
int n, x;
char vis[N];
int a[N], b[N], ans[N];
void work(){
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	for (re i = 1 ; i <= n ; ++ i)
		cin >> b[i];
	char can, cann;
	for (re who = 1 ; who <= n ; ++ who){
		memset(vis, false, sizeof(vis));
		vis[who] = true; cann = true; x = a[1] ^ b[who];
		for (re i = 2 ; i <= n ; ++ i){
			can = false;
			for (re j = 1 ; j <= n ; ++ j)// 判断a[i]和谁对应
				if (vis[j] == false and (a[i] ^ b[j]) == x)
					{vis[j] = true, can = true; break;}
			if (can == false)
				{cann = false; break;}
		}
		if (cann == true)
			ans[++ ans[0]] = x;
	}
	sort(ans+1, ans+ans[0]+1);
	cout << ans[0] << '\n';
	for (re i = 1 ; i <= ans[0] ; ++ i)
		cout << ans[i] << '\n';
}
#define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(f);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

T2 S

似乎是明白dp状态就好了

fijkc为选了iRjGkY,结尾为c的最小交换次数

显然的dp转移方程就从上一个球转移就好

注意遇到不合法状态时及时跳过

T2
#include <iostream>
#include <cmath>
#include <cstring>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define ABS(x) (((x) < 0) ? (-(x)) : (x))
#define N 405
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
/*
	我想知道我为啥知道每个点最后是换到哪里的(((
	是On扫一遍得出来吗
	按照题解思路走,逆序对个数..
	弔
	半懂不懂
	毕竟我似乎dp采药都不会
*/
int n, final_ans;
char s[N];
int plc[5][N];
int f[N>>1][N>>1][N>>1][3];// f[i][j][k][c]选了i个R,j个G,k个Y,结尾为c 只用开一半N是因为合法状态
void work(){
	cin >> n;
	cin >> s+1;
	cerr << sizeof(f) << '\n';
	for (re i = 1 ; i <= n ; ++ i){
		switch (s[i]){
			case('R'):{
				plc[1][++ plc[1][0]] = i;
				break;
			}
			case ('G'):{
				plc[2][++ plc[2][0]] = i;
				break;
			}
			case ('Y'):{
				plc[3][++ plc[3][0]] = i;
				break;
			}
		}
	}
	if (MAX(plc[1][0], MAX(plc[2][0], plc[3][0])) > ceil((double)n/2))
		{cout << -1 << '\n'; return ;}
	memset(f, 0x5f, sizeof(f));
	f[0][0][0][1] = f[0][0][0][2] = f[0][0][0][3] = 0;
	for (re now = 0 ; now <= n ; ++ now){
		for (re i = 0 ; i <= MIN(plc[1][0], now) ; ++ i){// Rのnum
			for (re j = 0 ; j <= plc[2][0] and i+j <= now ; ++ j){
				if (now-i-j > plc[3][0])// unavailable
					continue;
				if (i + 1 <= plc[1][0])
					f[i+1][j][now-i-j][1] = MIN(f[i+1][j][now-i-j][1], MIN(f[i][j][now-i-j][2], f[i][j][now-i-j][3])+ABS(now+1-plc[1][i+1]));
				if (j + 1 <= plc[2][0])
					f[i][j+1][now-i-j][2] = MIN(f[i][j+1][now-i-j][2], MIN(f[i][j][now-i-j][1], f[i][j][now-i-j][3])+ABS(now+1-plc[2][j+1]));
				if (now-i-j + 1 <= plc[3][0])
					f[i][j][now-i-j+1][3] = MIN(f[i][j][now-i-j+1][3], MIN(f[i][j][now-i-j][1], f[i][j][now-i-j][2])+ABS(now+1-plc[3][now-i-j+1]));
			}
		}
	}
	final_ans = MIN(f[plc[1][0]][plc[2][0]][plc[3][0]][1], MIN(f[plc[1][0]][plc[2][0]][plc[3][0]][2], f[plc[1][0]][plc[2][0]][plc[3][0]][3])) >> 1;
	cout << final_ans << '\n';
}
#define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(s);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

T3 Y

不会 咕

T3·暴力30pts
#include <iostream>
#include <unordered_map>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 2005
#define P 1000000007
#define PP 1000000000000007
#define base 133
#define mod %
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
/*
	最近老这么奇怪
	“都几点了”————陶
	bush,刚八点四十我就来开T3
	数学是吧 考数学是吧
	所有人同时进行,也就是不能接过来别人的球再给出
	有一个显然的O(n*ai)
	似乎可以拿到50pts
	坏耶,又是基于值域的算法
	刚九点半,再想想
	想不出来
	坏耶
	不对,时间复杂度好像是错的
	似乎是指数的
	超
	时间复杂度上界:O((max{ai}) ^ n)
	我超
	喜提30pts的好成绩
	忽然发觉
	这是个dp
	还和期望dp里有一道题挺像
    记搜搞不了因为太菜了
    而且该开T4了
    希望别爆零
*/
long long n, final_ans;
long long a[N], b[N];
unordered_map<long long, char> been;
long long XIN_team(int x, long long give, long long hsh, long long sum){
	/*cerr << x << _ << give << '\n';
	for (re i = 1 ; i <= n ; ++ i)
		cerr << b[i] << _;
	cerr << '\n';*/
	// cerr << x << _ << give << _ << hsh << _ << sum << '\n';
	if (hsh > PP)
		hsh -= PP;
	if (x == 1 and give == -114){
		long long res(0);
		// cerr << '\n';
		for (re i = 0 ; i <= a[1] ; ++ i){
			b[1] = a[1]-i;
			res += XIN_team(n, i, 1, 1);
		}
		return res;
	}
	if (x == 1){
		b[1] += give;
		sum *= b[1];
		hsh = (hsh * base mod PP) + b[1];
		if (hsh > PP)
			hsh -= PP;
		/*cerr << sum << '\n';
		for (re i = 1 ; i <= n ; ++ i)
			cerr << b[i] << _;
		cerr << '\n' << '\n';*/
		b[1] -= give;
		if (been[hsh] == true)
			return 0;
		else 
			{been[hsh] = true; return sum;}
	}
	// cerr << '\n';
	long long res(0);
	b[x] += give;
	for (re i = 0 ; i <= a[x] ; ++ i){
		b[x] += a[x] - i;
		res += XIN_team(x-1, i, (hsh*base mod PP) + b[x], sum*b[x]);
		b[x] -= a[x] - i;
	}
	b[x] = 0;
	return res;
}
void work(){
	cin >> n;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	if (n == 1)
		{cout << a[1] << '\n'; return ;}
	final_ans = XIN_team(1, -114, 1, 1);
	cout << final_ans << '\n';
}
#define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(y);
    #endif
    Fastio_setup();
    work();
    return GMY;
}

T4 o

也咕

暴力水20pts

嘉晚饭是真的

T4·暴力20pts
#include <iostream>
#include <map>
#include <algorithm>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x) freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout);
#define int long long
#define re register int
#define char_phi signed
#define MARK cout << "###"
#define MARKER "@@@"
#define LMARK "!!!~~~"
#define ZY " qwq "
#define _ ' '
#define Endl cout << '\n'
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define N 200005
#define QUERY 200005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL), cerr.tie(NULL);}
/*
	超
	为啥这么喜欢出同时往左往右的这种题?
	“原批是否对于高精度有特别的执着?”
	“原批是否对于板子题有特别的执着?”
	主席树是吧
	sandom_tree是吧
	按照题意模拟 O(n^3)
	水10pts
	样例都过了
	但是我知道会T飞
	显然
*/
int n, Q, final_ans, ed;
int a[N], ans[QUERY];
struct Question{
	int t, l, r, id;
	friend bool operator < (Question A, Question B){
		if (A.t != B.t)
			return A.t < B.t;
		else
			return A.id < B.id;
	}
}q[QUERY];
map<int, int> mp;
void work(){
	// cerr << "Ive been there" << '\n';
	cin >> n >> Q;
	for (re i = 1 ; i <= n ; ++ i)
		cin >> a[i];
	for (re i = 1 ; i <= Q ; ++ i)
		{cin >> q[i].t >> q[i].l >> q[i].r; q[i].id = i;}
	sort(q+1, q+Q+1);
	for (re i = 1 ; i <= Q ; ++ i)
		if (mp.find(q[i].t) == mp.end())
			mp[q[i].t] = i;
	int qid;
	ed = MIN(n, q[Q].t);
	for (re t = 1 ; t <= ed ; ++ t){
		// cerr << "EE" << '\n';
		for (re i = n ; i >= 2 ; -- i)
			if (a[i] < a[i-1])
				a[i] = a[i-1];
		/*for (re i = 1 ; i <= n ; ++ i)
			cerr << a[i] << _;
		cerr << '\n' << '\n';*/
		if (mp.find(t) != mp.end()){
			for (qid = (*mp.find(t)).second; (q[qid].t == t) ; ++ qid){
				final_ans = 0;
				for (re j = q[qid].l ; j <= q[qid].r ; ++ j){
					final_ans += a[j];
				}
				ans[q[qid].id] = final_ans;
			}
		}
	}
	for (re i = 1 ; i <= Q ; ++ i)
		cout << ans[i] << '\n';
}
/*
	tips:
	T4 无样例三
	样例三的输入是样例二的输出
*/
#define IXINGMY
char_phi main(){
    #ifdef IXINGMY
        FBI_OPENTHEDOOR(o);
    #endif
    Fastio_setup();
    work();
    return GMY;
}
posted @   char_phi  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示