B
//我是彩笔,没看出限制,行列变化后,前缀模三也不变,同余定理。
//反推出如果行列的模不同说明不可以
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<string> grid1(n), grid2(n);
vector<int> sr1(m, 0), sr2(m, 0), sc1(n, 0), sc2(n, 0);
int total_sum1 = 0, total_sum2 = 0;
for (int i = 0; i < n; ++i) {
cin >> grid1[i];
for (int j = 0; j < m; ++j) {
sr1[j] = (sr1[j] + (grid1[i][j] - '0')) % 3;
sc1[i] = (sc1[i] + (grid1[i][j] - '0')) % 3;
total_sum1 = (total_sum1 + (grid1[i][j] - '0')) % 3;
}
}
for (int i = 0; i < n; ++i) {
cin >> grid2[i];
for (int j = 0; j < m; ++j) {
sr2[j] = (sr2[j] + (grid2[i][j] - '0')) % 3;
sc2[i] = (sc2[i] + (grid2[i][j] - '0')) % 3;
total_sum2 = (total_sum2 + (grid2[i][j] - '0')) % 3;
}
}
bool ok = (total_sum1 == total_sum2);
for (int i = 0; i < n; ++i) ok &= (sc1[i] == sc2[i]);
for (int i = 0; i < m; ++i) ok &= (sr1[i] == sr2[i]);
cout << (ok ? "YES\n" : "NO\n");
}
return 0;
}
C
//直接上标准答案吧,写的比较优美
//就是一个分类加二分
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define ff first
#define ss second
#define pii pair<int,int>
#define vi vector<int>
#define vii vector<pair<int,int>>
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
vector<vi> val(3,vector<int>(n+1));
vector<vi> pf(3,vector<int>(n+1));
for(int i=0;i<3;i++){
for(int j=1;j<=n;j++){
cin>>val[i][j];
pf[i][j] = pf[i][j-1] + val[i][j];
}
}
bool ok = 0;
vi perm = {0,1,2};
int comp = (pf[perm[0]][n]+2)/3;
for(int i=0;i<6;i++){
int cur = 1;
while(cur <= n && pf[perm[0]][cur] < comp) cur++;
for(int j=cur+1;j<n;j++){
if(pf[perm[1]][j] - pf[perm[1]][cur] >= comp && pf[perm[2]][n] - pf[perm[2]][j] >= comp){
vii ans(3);
ans[perm[0]] = {1,cur};
ans[perm[1]] = {cur+1,j};
ans[perm[2]] = {j+1,n};
for(auto x: ans) cout<<x.ff<<' '<<x.ss<<' ';
cout<<'\n';
ok = 1;
break;
}
}
if(ok)break;
next_permutation(perm.begin(), perm.end());
}
if(!ok)cout<<-1<<'\n';
}
return 0;
}
C
//bfs水题
//但是有意思的是,题解给出一种好玩的解法
//如果存在两个连续的奇数单元格,它们都指向左,那么无论机器人如何选择路径,它都会在这两个单元格之间来//回穿梭,无法前进到右侧的单元格。(因为偶数在第二步会到偶数,奇数在第一步会到奇数)
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 1;
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int n;
bool check(int x, int y, vector<vector<bool>> &st) {
if (x < 0 || y < 0 || x >= 2 || y >= n || st[x][y]) return true;
return false;
}
void solve() {
cin >> n;
string s[2];
vector<vector<bool>> st(2, vector<bool>(n, false));
cin >> s[0] >> s[1];
deque<pii> dq;
dq.push_back({0, 0});
st[0][0] = true;
while (!dq.empty()) {
pii pos = dq.front();
int x = pos.first, y = pos.second;
dq.pop_front();
// cout << x << " " << y << "\n";
if (x == 1 && y == n - 1) {
cout << "YES\n";
return;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (check(nx, ny, st)) continue;
st[nx][ny] = true;
if (nx == 1 && ny == n - 1) {
cout << "YES\n";
return;
}
if (s[nx][ny] == '>'&&!check(nx,(ny+1),st)) {
dq.push_back({nx, ny+1});
st[nx][ny+1] = true;
} else if (s[nx][ny]=='<'&&!check(nx,(ny-1),st)) {
dq.push_back({nx, ny-1});
st[nx][ny-1] = true;
}
}
}
cout << "NO\n";
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
}
D
//数据量是5000,暴力枚举是n三(枚举长度,枚举每个,遍历相等)25*1e9.显然不对。但是仔细一想,只要长度不是1那就可能过,题解也是这样说的;
//时间上会有很多剪枝,所以可以过,真是神奇;
//cf前几道果然不用什么算法
//给我的感觉就是经验之谈
#include<bits/stdc++.h>
using namespace std;
void solve(){
string s="?";
string tmp;
cin>>tmp;
s+=tmp;
int n=tmp.size();
//cout<<tmp<<endl;
//cout<<s<<endl;
int len=n;
if(n&1) len--;
for(;len>=2;len-=2)
{
int d=((len)/2);
for(int i=1;i+len-1<=n;i++){
bool ok=true;
for(int j=i;j<i+d;j++){
if(s[j]==s[j+d]||s[j]=='?'||s[j+d]=='?') continue;
ok=false;
break;
}
if(ok){
cout<<len<<"\n";
return ;
}
}
}
cout<<0<<"\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}