Hihocoder 1632 : Secret Poems 思维|技巧

题意

定义一个矩阵 他有n*n大小 然后给出他的真实信息的走法 让我们变换走法 再次把真实信息填入矩阵中
n<=100

分析

可以发现原文的读取方式无非就是如此
(0,1)向左
(1,-1)左下
(1,0)向下
(-1,1)右上
1边界检查
(1,0)向下
(1,-1)左下
(0,1)向左
(-1,1)右上
2退出检查
观察发现其中下和左移动都是1步 走斜线都是走到头
所以可以用边界检查控制移动方向从而按照对应的移动方式还原真实信息
当经过1后 发现剩下的方向就是1处之前的顺序 倒着来
那么我们就可以用一个方向向量表示方向
然后到1处就 逆序遍历方向向量
注意n的奇偶情况下 路径不同 但都是在右上或左下 走逆序方向
发现n为奇数时 在右上逆向 n为偶数在左下逆向 然而分别都是走斜边到的这一点
那么我们就可以在走斜边的时候判断如果到了这两点 就把他们方向逆序化0
得到了密文信息 螺旋矩阵输入就可以了
就是边界检查什么的 还有控制移动的时候不好写 还原信息的过程易出错

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[105][105],ans[105][105];
int dir[][2] = {{0,1},{1,-1},{1,0},{-1,1}},dir2[][2] = {{0,1},{1,0},{0,-1},{-1,0}};
int main()
{
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
        string l;
        int x=1,y=1,tmp=1;
        l = a[x][y];//第一个字符要先加进去
        for(int i=0;;i=(i+tmp+4)%4){//方向变化 为了防止倒方向出现问题 还是再+4
            if(x==n&&y==n)break; //这句话比较奇怪 加在这里AC 下面的if-else 后面就RE 哪位细心地网友看出来为何了 可以留言一下
            if(i%2==0){
                x+=dir[i][0];
                y+=dir[i][1];
                l.append(1,a[x][y]);
            }
            else{
                while(x+dir[i][0]!=0&&x+dir[i][0]<=n&&y+dir[i][1]!=0&&y+dir[i][1]<=n){//边界判断用试加法 如果可行再加 因为一旦越界没有回来的向量
                    x+=dir[i][0];
                    y+=dir[i][1];               
                    l.append(1,a[x][y]);
                }
                if((x==1&&y==n)||(x==n&&y==1))tmp=-tmp;//当到左上或右下转换方向
            }

        }
        int t=0;
        x=1,y=1;
        ans[x][y]=l[t++];
        for(int i=0;t<=n*n-1;i=(i+1)%4){
            while(t<n*n&&x+dir2[i][0]>0&&y+dir2[i][1]>0&&x+dir2[i][0]<=n&&y+dir2[i][1]<=n&&ans[x+dir2[i][0]][y+dir2[i][1]]==0)
                ans[x+=dir2[i][0]][y+=dir2[i][1]]=l[t++];
        } 
        for(int i=1;i<=n;i++)printf("%s\n",ans[i]+1);
        memset(ans,0,sizeof(ans));
        memset(a,0,sizeof(a));
    }

    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值