SGU 109 Magic of David Copperfield II

题目大意:

n*n的图片,从左往右,从上到下,依次编号为1-n*n。

观众从图片1出发,按照魔术师所给的指令k1(k1>=n),移动k1步(只能上下左右),之后魔术师删除一些图片(观众当前所在图片之外的),再给指令k2(k2>k1),观众再移动k2步,魔术师再删除一些图片,如此下去,直到图片剩下最后一张。现在要求输出每次魔术师所给的指令k1、k2、……以及删除的图片。


分析:

1、每次删除的必然是给定k后,观众无法到达的图片。

2、删除时应保证图片间的连通性,可从外围删除来保证。

3、若观众移动奇数步,则观众必然可以从当前图片所在的副对角线(i+j=m1)走到另外一条副对角线(i+j=m2)上的某个图片,此时可删除i+j=m1上的所有图片

于是有了下面的删除方案:

1、首先第1步走n步,可以发现右下脚部分(副对角线i+j=n+2以下)是无法到达的,先将该部分删除。

2、考虑n,如果n为偶数,那么下次应该走n+1步;若n为奇数,则走n+2步,这样观众必然不会处于当前副对角线(i+j=n+2)上,此时将该副对角线上图片的删除。

3、此时n已经是奇数,每次+2,依次删除右下到左上的副对角线上的图片即可。


#include<iostream>
#include<cstdio>
using namespace std;

int main()
{
    int n,i,j,d,step;
    while(~scanf("%d",&n))
    {
        step=n;
        printf("%d",step);
        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j) if(i+j>n+2) printf(" %d",(i-1)*n+j);
        puts("");

        for(d=n+2;d>2;--d)
        {
            if(step&1) step+=2;
            else ++step;
            printf("%d",step);
            for(i=1;i<=n;++i)
                for(j=1;j<=n;++j) if(i+j==d) printf(" %d",(i-1)*n+j);
            puts("");
        }
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值