2020杭电多校 4L / HDU 6813 - Last Problem (构造/dfs)

HDU 6813 - Last Problem


题意

有个无限大的画板,初始均为空,张三想画出数字\(n\)

如果他想画下数字\(n\ (n\geq5)\),需要保证四周的数字为\(n-1,\ n-2,\ n-3,\ n-4\)

如果\(n\leq4\),只需要保证大于\(0\)的数字出现在四周即可

要求输出这样的画法,并且输出不超过\(5MB\)(理论上大概\(130W\)\(int\)类型,但根据SPJ限制好像最多只能走\(10W\)步)




思路

看起来好像瞎搜索都行,但有两条限制(或者说优化)

首先,如果要保证能画下数字\(n\),需要让\(n-1,\ n-2,\ n-3,\ n-4\)出现在其周围

于是就可以从数字\(n\)开始(随便确定一个起点)往四周dfs搜索即可

但是搜索的顺序并不是无序的:需要保证\(n-1\)\(n-4\)\(n-2\)\(n-3\))分隔在\(n\)的两侧才能保证不会出现搜索之间的覆盖

然后在搜索的过程中,如果周围已经出现了某个数字就不需要重新构造一遍了(好像懂的都懂???)




完整程序

下面为正确的代码其一(\(dx\)\(dy\)数组改掉试了挺多次,但只要满足上面说的条件都能过)

(15ms/1000ms)

#include<bits/stdc++.h>
using namespace std;

int dx[4]={0,-1,1,0},dy[4]={-1,0,0,1}; //"左上下右"的顺序
int mp[200][200]; //实测大概100*100就差不多了(吧)

void dfs(int x,int y,int v)
{
    if(v<=0)
        return;
    for(int i=0;i<4;i++) //按预定顺序搜索
    {
        int px=x+dx[i],py=y+dy[i];
        if(mp[px][py]!=v-i-1) //周围已经出现待构造的数字
            dfs(px,py,v-i-1);
    } //先构造出能让v填在(x,y)位置的图
    mp[x][y]=v; //再让v填在(x,y)位置
    cout<<x<<' '<<y<<' '<<v<<'\n';
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    dfs(100,100,n);
    return 0;
}


顺便放一个让人迷惑的标程???

#include<bits/stdc++.h>
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1,w=n;i<=n;i++,w--)
        for(int x=i,j=0;x>=1&&j<w;x-=2,j++)
            for(int y=x,k=0;y>=1&&k<w;y--,k++)
                printf("%d %d %d\n",i+k+j,k-j,y);
    return 0;
}

posted @ 2020-07-31 14:32  StelaYuri  阅读(253)  评论(0编辑  收藏  举报