feat: 添加矩阵对角线排序和V形对角线最长段算法

refactor: 优化最长公共递增子序列算法实现
This commit is contained in:
Zengtudor 2025-08-28 14:14:16 +08:00
parent 8b49a88aa9
commit 830b825fbf
3 changed files with 236 additions and 69 deletions

View File

@ -0,0 +1,94 @@
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
const vector<vector<int>> dir = {{-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
int n, m;
bool isValid(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
}
int getClockwiseTurn(int dir_idx) {
return (dir_idx + 1) % 4;
}
int getExpectedValue(int len) {
return (len % 2 == 0) ? 2 : 0;
}
int dfs_second_leg(const vector<vector<int>>& g, int r, int c, int len, int dir_idx) {
int max_len_from_here = len;
int next_r = r + dir[dir_idx][0];
int next_c = c + dir[dir_idx][1];
if (isValid(next_r, next_c) && g[next_r][next_c] == getExpectedValue(len + 1)) {
max_len_from_here = max(max_len_from_here, dfs_second_leg(g, next_r, next_c, len + 1, dir_idx));
}
return max_len_from_here;
}
int dfs_first_leg(const vector<vector<int>>& g, int r, int c, int len, int dir_idx) {
int max_len_found = len;
int turn_dir_idx = getClockwiseTurn(dir_idx);
int next_r_turn = r + dir[turn_dir_idx][0];
int next_c_turn = c + dir[turn_dir_idx][1];
if (isValid(next_r_turn, next_c_turn) && g[next_r_turn][next_c_turn] == getExpectedValue(len + 1)) {
max_len_found = max(max_len_found, dfs_second_leg(g, next_r_turn, next_c_turn, len + 1, turn_dir_idx));
}
int next_r_straight = r + dir[dir_idx][0];
int next_c_straight = c + dir[dir_idx][1];
if (isValid(next_r_straight, next_c_straight) && g[next_r_straight][next_c_straight] == getExpectedValue(len + 1)) {
max_len_found = max(max_len_found, dfs_first_leg(g, next_r_straight, next_c_straight, len + 1, dir_idx));
}
return max_len_found;
}
int lenOfVDiagonal(const vector<vector<int>>& g) {
if (g.empty() || g[0].empty()) return 0;
n = g.size();
m = g[0].size();
int ans = 0;
bool has_one = false;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (g[i][j] == 1) {
has_one = true;
for (int k = 0; k < 4; ++k) {
ans = max(ans, dfs_first_leg(g, i, j, 1, k));
}
}
}
}
if (has_one && ans == 0) return 1;
return ans;
}
};
int main(){
Solution s;
int ans = s.lenOfVDiagonal({{2,2,1,2,2},{2,0,2,2,0},{2,0,1,1,0},{1,0,2,2,2},{2,0,0,2,2}});
cout<<ans<<"\n";
}

View File

@ -1,81 +1,95 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
#include <ostream>
#include <tuple>
#include <stack>
#include <vector>
/*
using pii = std::pair<int, int>;
using ll = long long;
dp[i][j]=A前i个与字符串B前j个
5
1 4 2 5 -12
4
-12 1 2 4
*/
using ll = int64_t;
#define gdp(i,j,k)(std::get<k>(dp[i][j]))
int main(){
std::iostream::sync_with_stdio(false);
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
ll n,m;
std::cin>>n;
std::vector<ll> a(n+1);
for(ll i=1;i<=n;i++)std::cin>>a[i];
std::cin>>m;
std::vector<ll> b(m+1);
for(ll j=1;j<=m;j++)std::cin>>b[j];
std::vector<std::vector<std::tuple<ll,ll,ll>>>dp(n+1,std::vector<std::tuple<ll,ll,ll>>(m+1));
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
if(a[i]!=b[j]){
gdp(i, j, 0) = gdp(i-1,j,0);
gdp(i, j, 1)=i-1;
gdp(i, j, 2)=j;
}else{
ll maxprev=0;
for(ll k=1;k<j;k++){
if(b[k]<a[i]){
maxprev=std::max(maxprev,gdp(i-1,k,0));
gdp(i,j,1)=i-1;
gdp(i,j,2)=k;
}
int n, m;
std::cin >> n;
std::vector<ll> a(n + 1);
for (int i = 1; i <= n; ++i)
std::cin >> a[i];
std::cin >> m;
std::vector<ll> b(m + 1);
for (int i = 1; i <= m; ++i)
std::cin >> b[i];
std::vector<std::vector<int>> dp(n + 1, std::vector<int>(m + 1, 0));
std::vector<std::vector<pii>> path(n + 1, std::vector<pii>(m + 1, {0, 0}));
for (int i = 1; i <= n; ++i) {
int max_len = 0;
int predecessor_k = 0;
for (int j = 1; j <= m; ++j) {
dp[i][j] = dp[i - 1][j];
path[i][j] = {i - 1, j};
if (a[i] == b[j]) {
if (max_len + 1 > dp[i][j]) {
dp[i][j] = max_len + 1;
path[i][j] = {i - 1, predecessor_k};
}
}
if (b[j] < a[i]) {
if (dp[i - 1][j] > max_len) {
max_len = dp[i - 1][j];
predecessor_k = j;
}
gdp(i,j,0)=maxprev+1;
}
}
}
ll ans=0,maxi=0,maxj=0;
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
// printf("dp[%lld][%lld]=%lld\n",i,j,dp[i][j]);
if(ans<gdp(i,j,0)){
ans=gdp(i,j,0);
maxi=i;
maxj=j;
}
int max_lcsis = 0;
int end_j = 0;
for (int j = 1; j <= m; ++j) {
if (dp[n][j] > max_lcsis) {
max_lcsis = dp[n][j];
end_j = j;
}
}
std::vector<ll> ans2;
ans2.reserve(n);
// printf("maxi=%lld,maxj=%lld\n",maxi,maxj);
while(maxi>0){
ans2.push_back(a[maxi]);
ll tmpi=maxi;
maxi=gdp(maxi,maxj,1);
maxj=gdp(tmpi,maxj,2);
std::cout << max_lcsis << "\n";
if (max_lcsis > 0) {
std::stack<ll> result_stack;
int curr_i = n;
int curr_j = end_j;
while (curr_i > 0 && curr_j > 0) {
pii prev = path[curr_i][curr_j];
if (dp[curr_i][curr_j] > dp[prev.first][prev.second] && prev.second != curr_j) {
result_stack.push(a[curr_i]);
}
curr_i = prev.first;
curr_j = prev.second;
}
bool first = true;
while (!result_stack.empty()) {
if (!first) {
std::cout << " ";
}
std::cout << result_stack.top();
result_stack.pop();
first = false;
}
std::cout << "\n";
}
std::cout<<ans<<"\n";
std::reverse(ans2.begin(),ans2.end());
for(auto i:ans2){
std::cout<<i<<" ";
}
std::cout<<std::endl;
_Exit(0);
}
return 0;
}

View File

@ -0,0 +1,59 @@
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
#define pg(g)do{\
for(auto&i:(g)){\
for(auto&j:i){\
cout<<j<<",";\
}\
cout<<"\n";\
}\
}while(0)
class Solution {
public:
vector<vector<int>> sortMatrix(vector<vector<int>>& g) {
vector<int>p;
for(int i=0;i<g.size();++i){
int x=i,y=0;
p.clear();
do {
p.push_back(g[x][y]);
++x,++y;
}while (x<g.size()&&y<g[0].size());
sort(p.begin(),p.end(),greater<>());
x=i,y=0;
int tot=0;
do {
g[x][y]=p[tot++];
++x,++y;
}while (x<g.size()&&y<g[0].size());
}
// pg(g);
for (int j=1; j<g[0].size(); ++j) {
int x=0,y=j;
p.clear();
do{
p.push_back(g[x][y]);
++x;++y;
}while(x<g.size()&&y<g[0].size());
sort(p.begin(),p.end());
x=0,y=j;
int tot=0;
do {
g[x][y]=p[tot++];
++x,++y;
}while (x<g.size()&&y<g[0].size());
}
// pg(g);
return g;
}
};
int main(){
Solution s;
vector<vector<int>> v={{1,7,3},{5,8,2},{4,9,6}};
s.sortMatrix(v);
}