首页 > 其他分享 >ABC291题解(D-G)

ABC291题解(D-G)

时间:2023-03-29 09:04:26浏览次数:55  
标签:int 题解 void Solution ++ vector ABC291

ABC291

D - Flip Cards

Solution:

考虑DP,定义状态\(F_{i,0}\)为第\(i\)张卡片正面朝上的方案数,\(F_{i,1}\)为第\(i\)张卡片背面朝上的方案数,每次check是否相同然后转移即可

int f[N][2];
int a[N];
int b[N];
void solve(){
	int n;
	cin >> n;
	for (int i = 1;i <= n;i ++) {
		cin >> a[i] >> b[i];
	}
	f[1][0] = 1;
	f[1][1] = 1;
	for (int i = 2;i <= n;i ++) {
		f[i][0] = (f[i - 1][0] * (a[i - 1] != a[i]) + f[i - 1][1] * (b[i - 1] != a[i])) % mod;
		f[i][1] = (f[i - 1][0] * (a[i - 1] != b[i]) + f[i - 1][1] * (b[i - 1] != b[i])) % mod;
	}
	cout << (f[n][0] + f[n][1]) % mod << endl;
}

E - Find Permutation

Solution:

考虑到题目所说的大小关系,可以联系到是一个有向图的形式,如果\(a\)和\(b\)有一条有向边,则含义为\(a\leqslant b\),所以我们可以发现,其实题目只是求一个拓扑序,观察第二个样例,我们还可以发现不能同时有多个点在拓扑序的同一时刻入队,所以就构造完了。

vector<int> G[N];
queue<int> qq;
int c[N];
int d[N];
int n, m;
vector <int > ans;
int f[N];
bool topsort(){
	int z=0;
	for (int i=1;i<=n;i++){
		if (!d[i])qq.push(i),z++,ans.push_back(i);
	}
	while (!qq.empty()){
		if(qq.size() != 1) {
			return false;
		}
		int t = qq.front();
		qq.pop();
		for (int i : G[t]){
			d[i]--;
			if (!d[i]){
				qq.push(i);
				ans.push_back(i);
				z++;
			}
		}
	}
	return z==n;
}
void solve(){
	cin >> n >> m;
	map<PII,bool> mp;
	for (int i = 1;i <= m;i ++) {
		int x,y;
		cin >> x >> y;
		d[y]++;
		G[x].push_back(y);
	}
	if(topsort()) {
		cout << "Yes" << endl;
		int now = 1;
		vector<int> last(n + 1);
		for (int i : ans) {last[i] = now++;}
		for (int i = 1;i <= n;i ++) cout << last[i] << ' '; cout << endl;
	}
	else cout << "No" << endl;
}

F-Teleporter and Closed off

Solution:

观察到\(m \leqslant 10\),且题目要求的是不经过一个点的时候的最短路,所以对于不经过的点,我们只需要枚举其前面最多\(10\)个位置,他们是需要"跨过"当前不能经过的点的,所以DP先处理出来两个最短路,一个从\(1\)到后面的点的,一个从后面的点到\(n\)的最短路,枚举完点就可以很快的算出答案了。

int f[N][2];
void solve(){
	int n , m;
	cin >> n >> m;
	vector<string> s(n + 1);
	for (int i = 2;i <= n;i ++) f[i][1] = 1e18;
	for (int i = 1;i <= n - 1;i ++) f[i][0] = 1e18;
	for (int i = 1;i <= n;i ++) {
		cin >> s[i];
		s[i] = " " + s[i];
		for (int j = 1;j <= m && i + j <= n;j ++) {
			if(s[i][j] == '1') f[i + j][1] = min(f[i + j][1], f[i][1] + 1);
		}
	}
	for (int i = n;i >= 1;i --) {
		for (int j = 1;j <= m && i + j <= n;j ++) {
			if(s[i][j] == '1') {
				f[i][0] = min(f[i][0],f[i + j][0] + 1);
			}
		}
	}
	for (int i = 2;i <= n - 1;i ++) {
		int ans = 1e18;
		for (int j = max(1ll,i + 1 - m);j <= i - 1;j ++) {
			for (int k = i + 1 - j;k <= min(m , n);k ++) {
				if(s[j][k] == '1') {
					ans = min(ans , f[j][1] + f[j + k][0] + 1);
				}
			}
		}
		if(ans != 1e18)
		cout << ans << ' ';
		else 
		cout << -1 << ' ';
	}
}

G - OR Sum

Solution:

暴力的复杂度是\(O(N^{2})\),所以考虑优化。复杂度来自两个地方,一个是枚举循环的情况,\(O(N)\),还有是扫描一遍算或的值,\(O(N)\),前一个循环不好优化,因为每个数都很小,所以考虑优化后面这一个运算的复杂度。首先我们可以对每位进行分析,\(A|B = A + B - A \& B\),这样子拆开式子后,我们就可以发现,前两项会是一个定值,就是所有元素的和,将\(B\)倒序之后,后面一项,对于每一位的情况就是\(\sum_{i = 1}^{n}A_{i + k} \& B_{n - i}\),显然是个卷积的形式,二进制最多五位,做五次卷积分别算贡献就做出来了。

void solve(){
	int n;
	cin >> n;
	int s = 0;
	for (int i = 1;i <= n;i ++) cin >> A[i], s += A[i];
	for (int i = 1;i <= n;i ++) cin >> B[i], s += B[i];
	for (int c = 0;c < 5;c ++) {
        memset(f,0,sizeof(f));memset(g,0,sizeof(g));
		for (int i = 0;i < n;i ++) {
			f[i] = f[i + n] = (A[i + 1] >> c) & 1;
			g[i] = (B[n - i] >> c) & 1;
		}
    	poly_mul(f,g,2 * n);
		for (int i = 0;i < n;i ++) {
			ans[i] += f[n + i] * (1ll << c);
		}
	}
	int now = -1;
	for (int i = 0;i < n;i ++) {
		now = max(now , s - ans[i]);
	}
	cout << now << endl;
}

标签:int,题解,void,Solution,++,vector,ABC291
From: https://www.cnblogs.com/zwh-zzz/p/17267473.html

相关文章

  • 使用SQLALCHEMY 出现warning的问题解决
    运行程序时出现错误:UserWarning:NeitherSQLALCHEMY_DATABASE_URInorSQLALCHEMY_BINDSisset.DefaultingSQLALCHEMY_DATABASE_URIto"sqlite:///:memory:".'Neithe......
  • CF429D Tricky Function 题解 分治/平面最近点对
    题目链接:http://codeforces.com/problemset/problem/429/D题目大意:给定一个长度为\(n\)的数列\(a_1,a_2,\ldots,a_n\)。用\(s\)表示\(a\)的前缀和数组,即\(s_......
  • buu [CISCN] BadProgrammer题解
    [CISCN]BadProgrammer页面很长,有很多的按钮,但是点了之后都没反应查看源码、扫描打开到具体目录一个个目录点开看,在static/下找到了一个flag.ejs文件下载,打开......
  • [ARC131D] AtArcher 题解
    题意数轴上有一个箭靶以\(0\)为轴心左右对称,给定每个得分区域的范围和分值,要求射\(N\)支箭在靶上,且任意两支箭的距离不少于\(D\),求最大得分。保证从中心向两侧分数不......
  • android:state_pressed标签失效或android:state_enabled标签失效问题解决
    问题描述:android:state_pressed标签失效或android:state_enabled标签失效,点击不会变色,可用/不可用时不会变色。 <?xmlversion="1.0"encoding="utf-8"?><selector......
  • 省选武汉联测 13 题解
    省选模拟赛俩构造一交互挺nm逆天。赛后题解区就一句Surprise!!!没题解也挺nm逆天。那建议组题人的马先消失一下。这时候就体现学长博客的重要性了。搜关键词搜到三......
  • Conda in Windows under MSYS2 and Zsh 的问题解决
    CondainWindowsunderMSYS2andZsh的问题解决在Window11上使用gitbash安装zsh,并配置p10k主题,主要问题就是prompt中无法显示condaenv;condaactivate/deactivate......
  • 【题解】[SDOI/SXOI2022] 小 N 的独立集(dp of dp)
    题目分析:就借助这个题稍微说一下\(dp\)套\(dp\)。对于\(dp\)套\(dp\)其解决的问题是:若给定某一具体情况则答案十分好求,现要求对于所有的情况的答案进行统计。这......
  • 【题解】[HNOI2007]梦幻岛宝珠
    题目分析:对于这种某一个值很大另一个值很小的背包题,就是要求找特殊性质。既然每一个\(w\)都可以写成\(a\times2^b\)的性质,就可以对于每一个\(b\)单独做背包,这样......
  • 【题解】[APIO2010] 信号覆盖
    题目分析:其实就是涉及四个点之间的位置关系,三个点形成圆判断是否包含另一个点。考虑四个点之间形成的多边形只可能是凸四边形或者是凹四边形,如下图所示:(上图为凸多边形)......