题意:象棋上的马可以向八个方向出棋,问一个马棋在走n步后,棋盘内有几个格子是有可能被走过的
想象一下出棋的过程,应该是一个由中心棋子不断向外扩散的画面,而且外层的棋子可能会相互覆盖,再看题目给出的样例数据,感觉应该是有规律可以找的,于是打表...
打表就用
bfs
的思想一层一层往外推
...
打表的结果是酱紫的->
第一列是答案,第二列是
n+1
步的答案与
n
步的答案只差,第三列是他们差的差
可以非常开心得看到第三列的答案在第五步之后一直为28!!
我们可以凭着这一点写出答案啦!!
不过在写的时候,要注意这道题数据
long long
会爆,需要用到无符号整形就能过了。
笔者因为这一点贡献了两个WA /(ㄒoㄒ)/~~
后来测试
1e9
的时候发现数据爆了才换成
unsigned long long
下面是打表和答案的代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
using namespace std;
int gram[505][505];
struct point{
int x,y;
int layer;
};
int dir[8][2] = {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};
int main()
{
memset(gram,0,sizeof(gram));
gram[205][205]=1;
queue<point> q;
point s;
s.x=100;s.y=100;
s.layer=0;
q.push(s);
int ans=1;
int ttt,tt;
for(int i=0;i<50;i++){
ttt = tt;
tt = 0;
while(1){
point p = q.front();
if(p.layer==i+1)
break;
q.pop();
for(int j=0;j<8;j++){
if(gram[p.x+dir[j][0]][p.y+dir[j][1]]==0){
ans++;
tt++;
point np;
np.layer=i+1;
np.x=p.x+dir[j][0];
np.y=p.y+dir[j][1];
q.push(np);
gram[p.x+dir[j][0]][p.y+dir[j][1]]=1;
}
}
}
printf("%dlayer: %d %d %d\n",i+1,ans,tt,tt-ttt);
}
return 0;
}
#include <iostream>
#include <stdio.h>
using namespace std;
int ans[7]={1,9,41,109,205,325,473};
int main()
{
int t;
scanf("%d",&t);
unsigned long long num;
for(int kase=1; kase<=t;kase++){
scanf("%llu",&num);
if(num<=6)
printf("Case #%d: %d\n",kase,ans[num]);
else{
unsigned long long t = num-6;
unsigned long long anss=473;
anss+=148*t;
unsigned long long tt = ((1+t)*t)/2;
anss+=28*tt;
printf("Case #%d: %llu\n",kase,anss);
}
}
return 0;
}