C
//两个点
//1:修改后出现的点必须在md中出现,
//2:最后一个点必须是出现在修改后的数组(用于可以覆盖其他所有非出现的点压)。
#include <bits/stdc++.h>
using namespace std;
int t;
void solve(){
int n;
cin>>n;
vector<int> a(n);
vector<int> b(n);
for(int i=0;i<n;i++) cin>>a[i];
map<int,int> mb;
bool tag=true;
for(int i=0;i<n;i++) {cin>>b[i];
mb[b[i]]++;
}
int m;
cin>>m;
vector<int> d(m);
map<int,int> md;
for(int i=0;i<m;i++) {
cin>>d[i];
md[d[i]]++;
}
if(!mb[d[m-1]]){
cout<<"NO\n";
return ;
}
int cnt=0;
for(int i=0;i<n;i++){
if(a[i]!=b[i]&&!md[b[i]]){
cout<<"NO\n";
cnt++;
return ;
}else if(a[i]!=b[i]&&md[b[i]]){
md[b[i]]--;
}
}
if(cnt>d.size()){
cout<<"NO\n";
return ;
}
cout<<"YES\n";
}
int main(){
cin>>t;
while(t--){
solve();
}
}
B
//无需多言,按照样例模拟,就可以贪心的将大于四周的数字变成四周最大的就可以
#include <bits/stdc++.h>
using namespace std;
int n,m;
bool check(int x,int y){
if(x<0||x>=n||y<0||y>=m) return true;
return false;
}
int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
void solve(){
cin>>n>>m;
vector<vector<int>> g(n+1, vector<int>(m+1, 0));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>g[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int mmax=0;
for(int k=0;k<4;k++){
int nx=i+dx[k],ny=j+dy[k];
if(check(nx,ny)) continue;
mmax=max(mmax,g[nx][ny]);
}
if(g[i][j]>mmax) g[i][j]=mmax;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<g[i][j]<<" ";
}
cout<<"\n";
}
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}
C
//无需多言,贪心,和之前的有点像的就是有个覆盖低贡献的
#include <bits/stdc++.h>
using namespace std;
void solve(){
int n,m;
cin>>n>>m;
string s;
cin>>s;
vector<int> index(m);
for(int i=0;i<m;i++) cin>>index[i];
//cout<<"\n";
string b;
cin>>b;
sort(index.begin(),index.end());
index.erase(unique(index.begin(),index.end()),index.end());
//for(int i=0;i<index.size();i++) cout<<index[i]<<" ";
sort(b.begin(),b.end());
//cout<<b<<"\n";
int j=0;
for(auto i:index){
s[i-1]=b[j++];
}
cout<<s<<"\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}
D
//我用的是dp,答案直接用结论,我想了一下没深入就去dp;
//题解分类1 n>3,有零 2有1用加 3无1用乘法。其实dp也可以用这个角度
//但是我直接用传统的方法设计状态,前i个选j个状态机表示第i个选没选
//题目要的是n n-1 1 但是循环状态还是要设计成 i~n,j~i;(j要等于i,只是输出时候到n01)
//集合dp,分为选和不选,乘和加
//状态转移式子要细细看一下
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
if (n == 1) { cout <<s<< endl; return; }
else if(n==2){ cout<<(s[0]-'0')*10+s[1]-'0'<<endl;return ;}
else if(n>3&&s.find('0')!=-1){
cout<<"0\n";
return ;
}
vector<vector<vector<ll>>> dp(n+1, vector<vector<ll>>(n+1, vector<ll>(2, INT_MAX)));
dp[1][0][0] = 0;
dp[1][1][1] = s[0] - '0';
dp[2][1][0]=dp[1][1][1];
dp[2][2][0]=dp[1][1][1];
dp[2][2][1]=min(dp[1][1][1]+s[1]-'0',dp[1][1][1]*(s[1]-'0'));
dp[2][1][1]=(s[0]-'0')*10+s[1]-'0';
for (int i = 3; i <= n; i++) {
for (int j = 0; j <=n; j++) {
dp[i][j][0] = dp[i-1][j][1];
ll one=s[i-1]-'0';
ll two = (s[i-2]-'0')*10 + (one);
if(j){
dp[i][j][1] = min(dp[i][j][1], dp[i-1][j-1][0] * two);
dp[i][j][1] = min(dp[i-1][j-1][0] + two, dp[i][j][1]);
dp[i][j][1] = min(dp[i][j][1],dp[i-1][j-1][1]*one);
dp[i][j][1] = min(dp[i][j][1],dp[i-1][j-1][1]+one);
}
}
}
cout << dp[n][n-1][1] << endl;
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
}