zoukankan      html  css  js  c++  java
  • [规律]跳马

    题目描述

    一个骑士在一个无限大的国际象棋棋盘里跳。一开始,这个国际象棋棋盘的每一个格子都是被标记为未被走过的,而骑士一开始可以以任意的一个格子作为起点,并且这个格子标记为走过。然后,他可以以如下图的规则跳N次,每一个他所到过的格子都会被标记为已经走过。
     
    现在,我们需要知道在N次跳跃之后,有多少个格子可能被标记为走过。

    输入

    第一行一个整数T,表示数据组数
    接下来T行,每行一个整数N

    输出

    共T行,每行一个整数,表示对应测试数据的答案

    样例输入

    3
    0
    1
    7
    

    样例输出

    1
    9
    649
    

    提示

    对于30%的数据,1<=T<=10,N<=1,000
    对于60%的数据,1<=T<=100,N<=1,000,000
    对于100%的数据,1<=T<=100,000,N<=1,000,000,000

     
    思路:先把n=1~10的结果用bfs求出并打成表,发现 结果的增量(a[n]=ans[n]-ans[n-1]) 的增量(b[n]=a[n]-a[n-1]) 在n>=6时总为28
    于是可以推出n>=4时求结果的公式 为:n-=3,ans=(14n+92)(n-1)+205
     
    AC代码:
    #include <iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define N 5010
    typedef unsigned long long ll;
    using namespace std;
    /*打表部分
    struct Node{
      ll x,y,step;
    };
    ll n;
    ll ans[110];
    ll b[110];
    ll dire[8][2]={-2,1,-1,2,1,2,2,1,-2,-1,-1,-2,1,-2,2,-1};
    queue<Node> q;
    bool vis[N][N];
    
    ll bfs(){
      ll ret=0;
      while(!q.empty()) q.pop();
      memset(vis,0,sizeof(vis));
      Node sta;
      sta.x=1000; sta.y=1000; sta.step=0; vis[sta.x][sta.y]=1;
      q.push(sta);
      while(!q.empty()){
        Node head=q.front();
        q.pop();
        ret++;
        for(ll i=0;i<8;i++){
            Node nxt;
            nxt.x=head.x+dire[i][0];
            nxt.y=head.y+dire[i][1];
            nxt.step=head.step+1;
            if(nxt.x>=0&&nxt.x<N&&nxt.y>=0&&nxt.y<N&&!vis[nxt.x][nxt.y]&&nxt.step<=n){
                vis[nxt.x][nxt.y]=1;
                q.push(nxt);
            }
        }
      }
      return ret;
    }
    
    int main()
    {
        for(n=1;n<=10;n++){
            ans[n]=bfs();
            printf("ans[%lld]=%lld",n,ans[n]);
            if(n!=1) {
                    b[n]=ans[n]-ans[n-1];
                    printf(" %lld",b[n]);
                    if(n!=2) printf(" %lld
    ",b[n]-b[n-1]);
                    else printf("
    ");
            }
            else printf("
    ");
        }
        return 0;
    }
    */
    ll a[4]={1,9,41,109};//n=0~3时的结果
    int main(){
      ll t;
      scanf("%llu",&t);
      while(t--){
        ll n;
        scanf("%llu",&n);
        if(n<=3) printf("%llu
    ",a[n]);
        else {
            n-=3;
            ll ans=(14*n+92)*(n-1)+205;
            printf("%llu
    ",ans);
        }
      }
      return 0;
    }
     
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    SQL Server 数据库定时自动备份
    SQL SERVER 2012设置自动备份数据库
    SyncNavigator 数据库同步软件怎么用?
    SyncNavigator下载|SyncNavigator数据库同步软件 v8.4.1
    关于数据同步的几种实现
    课堂练习-找水王:
    软件工程第十四周总结
    Alpha版(内部测试版)发布
    软件工程第十三周总结
    意见评论汇总
  • 原文地址:https://www.cnblogs.com/lllxq/p/9035725.html
Copyright © 2011-2022 走看看