题意
有个无限大的画板,初始均为空,张三想画出数字(n)
如果他想画下数字(n (ngeq5)),需要保证四周的数字为(n-1, n-2, n-3, n-4)
如果(nleq4),只需要保证大于(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<<'
';
}
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
",i+k+j,k-j,y);
return 0;
}