首页 > 其他分享 >CSP-S模拟11

CSP-S模拟11

时间:2022-09-26 19:45:18浏览次数:45  
标签:11 typedef code const int long maxn CSP 模拟

A. 回文

经典 \(dp\) ,两边同时走,三维状态表示走了几步,左上出发走到哪行,右下出发走到哪行

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 505;
const int mod = 993244853;
int f[2][maxn][maxn], n, m, nt, zt;
char mp[maxn][maxn];
void add(int &x, int y){
	x += y; x = x >= mod ? x - mod : x;
}
bool check(int x, int y){return x > 0 && y > 0 && x <= n && y <= m;}
bool can(int x, int y, int xx, int yy){
	// printf("chk : %d %d %d %d\n", x, y, xx ,yy);
	return check(x, y) && check(xx, yy) && mp[x][y] == mp[xx][yy];
}
void upd(int x, int y, int xx, int yy){
	if(xx < x || yy < y)return;
	if(can(x, y + 1, xx, yy - 1))add(f[nt][x][xx], f[zt][x][xx]);
	if(can(x, y + 1, xx - 1, yy))add(f[nt][x][xx - 1], f[zt][x][xx]);
	if(can(x + 1, y, xx, yy - 1))add(f[nt][x + 1][xx], f[zt][x][xx]);
	if(can(x + 1, y, xx - 1, yy))add(f[nt][x + 1][xx - 1], f[zt][x][xx]);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; ++i)scanf("%s",mp[i] + 1);
	f[0][1][n] = mp[1][1] == mp[n][m];
	int c = (n + m - 1) / 2;
	if((n + m) % 2 == 0)++c;
	for(int i = 1; i < c; ++i){
		nt = i & 1, zt = 1 - nt;
		int sum = i + 1;
		int up = min(n, sum - 1);
		for(int d1 = 1; d1 <= up; ++d1)
			for(int d2 = 1; d2 <= up; ++d2){
				int x = d1, y = sum - d1;
				int xx = n - d2 + 1, yy = m + n - i - xx + 1;
				if(x <= xx && y <= yy && f[zt][x][xx])upd(x, y, xx, yy);
				f[zt][x][xx] = 0; 
			}
	}
	int ans = 0;
	nt = c & 1;
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= n; ++j){
			int x = i, y = c - i + 1;
			int xx = n - j + 1, yy = m + n - c - xx + 1;
			// printf("%d %d %d %d\n",x, y, xx, yy);
			if(x <= xx && y <= yy && check(x, y) && check(xx, yy))add(ans, f[1 - nt][x][xx]);
		}
	}
	printf("%d\n",ans);
	return 0;
}

B. 快速排序

你如果像我一样一直考虑如何优化他的代码,别想了,没救

发现就是把数移到前面比他大的数前面,整体还是有序的

那么每次二分一下就行了

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 500005;
const int inf = 2147483647;
int n;
char c[15];
int a[maxn], b[maxn];
bool vis[maxn];
void solve(){
	scanf("%d",&n);
	for(int i = 1; i <= n; ++i){
		a[i] = 0;
		scanf("%s", c + 1);
		if(c[1] == 'n')a[i] = inf;
		else{
			int s = strlen(c + 1);
			for(int j = 1; j <= s; ++j){
				a[i] = (a[i] << 3) + (a[i] << 1) + (c[j] ^ 48);
			}
		}
	}
	int p = 0;
	for(int i = 1; i <= n; ++i)if(a[i] != inf)b[++p] = a[i];
	sort(b + 1, b + p + 1);
	int mx = 0;
	int l = 1;
	for(int i = 1; i <= n; ++i){
		if(a[i] == inf)printf("nan ");
		else{
			if(mx <= a[i]){
				int now = lower_bound(b + l, b + p + 1, a[i]) - b;
				for(int j = l; j <= now; ++j)printf("%d ",b[j]);
				l = now + 1;
			}
			mx = max(a[i], mx);
		}
	}
	// for(int i = 1; i <= n; ++i)if(a[i] == inf)printf("nan "); else printf("%d ",a[i]);
	printf("\n");
}
int main(){
	int t; scanf("%d",&t);
	for(int i = 1; i <= t; ++i)solve();
	return 0;
}

C. 混乱邪恶

奇妙构造

题解讲的很好,我就不废话了

image

关于 \(\sum d_i\) 那个式子,其实就是 \([l,r]\) 有 \(r - l + 1\) 个数,但是 \(d_i = r - l\) 两个数就会少一个,一共少 \(n/ 2\)

右边式子是题目保证

code
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 1000005;

int n, m, a[maxn], now[maxn << 2 | 1];
int ans[maxn], id[maxn];
int cnt;
struct node{int idx, idy, val;}d[maxn << 2 | 1];
struct note{
	int val, id;
	friend bool operator < (const note &x, const note &y){
		return x.val < y.val;
	}
};
multiset<note>s;
queue<int>Q;
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; ++i)cin >> a[i];
	for(int i = 1; i <= n; ++i)id[a[i]] = i;
	sort(a + 1, a + n + 1);
	int p = 0;
	for(int i = n; i >= 1; i -= 2){
		d[++p].val = a[i] - a[i - 1];
		d[p].idx = a[i]; d[p].idy = a[i - 1];
	}
	for(int i = 1; i <= p; ++i)s.insert({d[i].val, i});
	int q = p;
	for(int i = 1; i < p; ++i){
		auto be = s.begin(), en = --s.end();
		d[++q].idx =(*en).id;
		d[q].idy = (*be).id;
		d[q].val = (*en).val - (*be).val;
		s.erase(be); s.erase(en);
		s.insert({d[q].val, q});
	}
	int root = (*s.begin()).id;
	now[root] = 1; Q.push(root);
	while(!Q.empty()){
		int x = Q.front(); Q.pop();
		if(x <= p)continue;
		now[d[x].idx] = now[x];
		now[d[x].idy] = -now[x];
		Q.push(d[x].idx);
		Q.push(d[x].idy);
	}
	for(int i = 1; i <= p; ++i)ans[id[d[i].idx]] = now[i], ans[id[d[i].idy]] = -now[i];
	printf("NP-Hard solved\n");
	for(int i = 1; i <= n; ++i)printf("%d ",ans[i]);
	return 0;
}

D. 校门外歪脖树上的鸽子

咕咕咕

code

标签:11,typedef,code,const,int,long,maxn,CSP,模拟
From: https://www.cnblogs.com/Chencgy/p/16732123.html

相关文章

  • 32nd 2022/8/5 模拟赛总结21
    这次问题所在是卡常,优化以及DP,和组合数嗯,还有如T3样子的DP,一脸懵逼,因为根本看不出来是DP,只觉得与组合数有些联系还有阔别已久的矩阵乘法,再次回归,需要复习,可以将前面的矩......
  • 35th 2022/8/9 模拟赛总结24
    这次可还行?又是发呆2h,然后亿脸懵逼,但是居然没有掉下去难道我的实力真的上来了?!!这一个暑假眼看就在机房中见到了尽头——8/17,然后作业也直接选择“鬼压床”,上来硬刚,规划......
  • 34th 2022/8/8 模拟赛总结23
    这次赛时不错,因为这次T1直接拿下,T3常数小也拿到了最高暴力然后T2大家都懵逼,T4也get到了暴力,于是——rk1只能说NB了当然还是戒骄戒躁,其实这次是真的不错,因为还有几个DJ......
  • 33rd 2022/8/6 模拟赛总结22
    这次还是很逊,又考炸,T1都没签上到,T4没\(longlong\)->0,数据都没看清T1死在了边界条件,真烦,不过这也说明自己不够细心,以后需要注意才是T2是一道挺好想的东西,但T1调试过久,故......
  • 36th 2022/8/11 模拟赛总结25
    这次真的不好,比赛一开始,揪着T1不放,当时脑子还短路,没想到讲循环一个个压回去,就是坐在那不停地想:斐波那契数列该乘什么……根本就像在发呆一样,足足发了一个钟,然后突然想到,可......
  • 9.26-CSP-S模拟12
    T1开挂比较水的贪心题,可以证明一定只包含不相交,拿个栈就很好做了。点击查看代码#include<bits/stdc++.h>typedeflonglongll;typedefunsignedlonglongull;ty......
  • CF1155D 题解
    题目传送门题目分析说实话,第一眼这题以为是贪心...(事实上我看所有动态规划都像贪心)。然后接着发现贪心明显做不了,又看见最大子段和,很容易联想到\(\text{dp}\)。在设计......
  • Win10使用打印机0x0000011b错误 如何处理(没有KB5005565补丁如何解决??)
    1.排查问题win10连接打印机共享错误显示0x0000011b怎么解决?很多用户在更新了windows系统的最新补丁后,突然发现自己打开打印机的时候提示“无法连接到打印机,错误为0x000......
  • CSP2022 S2 练习二 题解
    ArbitrageA货币可以以\(x\)的汇率兑换B货币,就从A向B连一条权值为\(x\)的边,改一下\(Floyd\)即可。点击查看代码#include<iostream>#include<string>#i......
  • redis curd 操作故障模拟
    1、下载对应的包,并编译gitclonehttps://gitlab.onemt.co/onemt-injection/redis-injection.gitmakebuild或者下载这个链接中的可执行文件 https://files.cnblogs......