CF2242D Two Digit Strings

CF2242D Two Digit Strings

唐题,但是忘了 \(LCS\) 所以没写出来……

注意到题目可以转化成找 \(x\) 个断点,把数组分成 \(x\) 段,每段求和取模,使最终 \(a = b\),求最大的 \(x\)。

根据余数加法的运算性质,每段和的模相同等价于断点前缀和的模相同。

因此我们先对两个数组分别求前缀和,然后求 \(LCS\) 就做完了。

\(-1\) 的条件是 \(\sum_{i = 1}^{n}a_i \equiv \sum_{i = 1}^{m}b_i \pmod{10}\) 不成立。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
using namespace std;
using ll = long long;
const int N = 1e4;
int n, m, T;
int f[N][N], s[N], t[N];
char a[N], b[N];
void Main(){
	cin >> a >> b;
	n = strlen(a);
	m = strlen(b);
	F(i, 0, n - 1){
		s[i + 1] = (s[i] + a[i] - '0') % 10;
//		printf("%d ", s[i + 1]);
	}
//	printf("\n");
	F(i, 0, m - 1){
		t[i + 1] = (t[i] + b[i] - '0') % 10; 
//		printf("%d ", t[i + 1]);
	} 
//	printf("\n");
	if(s[n] != t[m]){
		cout << -1 << '\n';
		return ; 
	}
	F(i, 1, n){
		F(j, 1, m){
			f[i][j] = max(f[i][j - 1], f[i - 1][j]);
			if(s[i] == t[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
		}
	}
	cout << f[n][m] << '\n';
	f[0][0] = f[1][0] = f[0][1] = f[1][1] = 0;
	return ;
} 
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	while(T --) Main(); 
	return fflush(0), 0;
}
posted @ 2026-09-06 20:50  superl61  阅读(6)  评论(0)    收藏  举报