hihoCoder 1632 secret poem (2017北京赛区)

本文介绍了一种基于两张特定顺序的二维数组进行元素填充的算法实现。通过定义两个指针分别遍历左右两个矩阵,并根据指定路径进行元素复制,最终输出目标矩阵。算法采用暴力模拟方法,适用于特定的路径填充问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

给你两张图,首先按第一张图的指定顺序读取字母,然后再按第二张图指定的顺序填入数组。最后输出此数组。

这里写图片描述

input:

5
THSAD
IIVOP
SEOOH
RGETI
YMINK

output:

THISI
POEMS
DNKIA
OIHTV
OGYRE

左边的图其实就类似于cantor表的顺序,右边的图类似于蛇形矩阵。
没有什么技巧,就是暴力模拟。
定义两个(x1,y1) , (x2,y2) , (x1,y1) 属于左边, (x2,y2)属于右边。 每当左图走一次,右图有跟着走一次,然后赋值res[x2][y2] = mp[x1][y1]即可。
注意走到一定条件要转向,可以用哨兵变量来判断转哪个方向。
具体代码:

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 100 + 10;

int main(){
    int n;
  //  freopen("/Users/user/Desktop/1.txt","r",stdin);
    while(cin >> n){
        char mp[maxn][maxn];
        char tmp[maxn][maxn];
        int vis[maxn][maxn]; // 用于蛇形矩阵判断是否已走过
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < n; ++i){
            cin >> mp[i];
        }
        bool turn1 = true, turn2 = false;//对应cantor图的斜方向的走向
        bool go1 = true, go2 = false;//对应 cantor图边缘的走向,一开始往右走
        bool t1 ,t2,t3,t4;//对应蛇形矩阵右下左上的走向
        t2 = t3 = t4 = false;
        t1 = true;//一开始走右边
        int r1 = 0, c1 = 0;//x1,y1
        tmp[0][0] = mp[0][0];
        vis[0][0] = 1;
        int ptrr = 0; int ptrc = 0;// x2,y2
        int tmpr = 0, tmpc = 0;//用来判断是否有移动,因为在转向的时候坐标不会改变,详情可以看下面代码。
        int tr = 0, tc = 0;//用来判断是否有移动
        int cnt = 1;//用来计数蛇形矩阵是否填满
        while(r1 != n-1 || c1 != n-1){
            if(go1) { // 右上边界
                if(c1 + 1 < n)
                    c1 += 1; 
                else r1 += 1;
                go1 = false; turn1 = true;
            }
            else if(go2){ //左下边界
                if(r1 + 1 < n)
                    r1 += 1;
                else
                    c1 += 1;
                go2 = false;
                turn2 = true;
            } 
            else if(turn1){//斜下
                if(r1+1 < n && c1-1 >= 0){
                    r1 += 1 ; c1 -= 1;
                }
                else{ 
                    turn1 = false; go2 = true;
                }
            }
            else if(turn2){//斜上
                if(r1-1 >= 0 && c1+1 < n){
                    r1 -= 1; c1 += 1;
                }
                else{
                    turn2 = false; go1 = true;
                }
            }
            if(tmpc == c1 && tmpr == r1) continue;//当走到边界如0,n-1时需要转向,但坐标是不会变的
            else {
                tmpc = c1; tmpr = r1;
            }
            while(tr == ptrr && tc == ptrc && cnt != n*n){//同理
                if(t1) {//右
                    if(ptrc+1 == n || (ptrc+1<n && vis[ptrr][ptrc+1] == 1)){
                        t1 = false; t2 = true; t3 = false; t4 = false;
                    }
                    else ptrc++;
                }
                else if(t2){//下
                    if(ptrr+1 == n ||(ptrr+1 < n && vis[ptrr+1][ptrc] == 1)){
                        t2 = false; t3 = true; t1 = false; t4 = false;
                    }
                    else ptrr++;
                }
                else if(t3){//左
                    if(ptrc-1 < 0 || (ptrc-1>=0&&vis[ptrr][ptrc-1] == 1)){
                        t3 = false; t1 = false; t2 = false; t4 = true;
                    }
                    else ptrc--;
                }
                else if(t4){//上
                    if(ptrr-1 < 0 ||(ptrr-1>=0 && vis[ptrr-1][ptrc] == 1)){
                        t2 = t3 = t4 = false;
                        t1 = true;
                    }
                    else ptrr--;
                }
                vis[ptrr][ptrc] = 1;
            }
            tr = ptrr; tc = ptrc;
            tmp[ptrr][ptrc] = mp[r1][c1];
            cnt++;
        }
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j)
                cout << tmp[i][j];
            cout << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值