CodeForces 385E Bear in the Field

来源:互联网 发布:淘宝漏洞买东西不花钱 编辑:程序博客网 时间:2024/04/27 21:32

题意:

一只熊从(sx,sy)开始走  速度为(dx,dy)  每一秒钟速度的两个维度同时加上所在坐标的和(即 +x+y)然后走一步

求  T秒钟后熊站在哪


思路:

T无比的大不可能是暴力的  于是想到两个可能

一是这个路径有循环有规律可以排除好多步

二是能构造出一个表示他行为的矩阵用快速幂做

由于规律很难找到  所以可以列一下他的状态变化  (x,y,dx,dy,i) 表示i时刻熊站在(x,y)处速度向量(dx,dy)

它的下一个状态是 ( 2x+y+dx+i , x+2y+dy+i , x+y+dx , x+y+dy , i+1 )  根据此构造矩阵

为了方便可以把平面从(1,1)平移到(0,0)  这时速度需要+2 (因为速度每次+x+y  x和y都-1则速度都+2)

所以我的矩阵对应常数的地方为2  之所以敢改动矩阵是因为F与fzc乘一次后除了第一列其余全是0

详见代码


其实我的思路不是很好  有队友master的帮助才搞定了这题…

http://kmjp.hatenablog.jp/entry/2014/01/25/1000  这份题解思路简单些  不过是日语的要用翻译软件


代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;typedef __int64 uint64;const int mat_n=6;uint64 n,sx,sy,dx,dy,t;uint64 fzc[6][6];uint64 F[6][6]={    {2,1,1,0,1,2},    {1,2,0,1,1,2},    {1,1,1,0,1,2},    {1,1,0,1,1,2},    {0,0,0,0,1,1},    {0,0,0,0,0,1}};void matrix_mul(uint64 a[][mat_n],uint64 b[][mat_n],uint64 mod){    uint64 c[mat_n][mat_n];    int i,j,k;    for(i=0;i<mat_n;i++)    {        for(j=0;j<mat_n;j++)        {            c[i][j]=0;            for(k=0;k<mat_n;k++)            {                c[i][j]=(c[i][j]+(a[i][k]*b[k][j])%mod)%mod;            }        }    }     for(i=0;i<mat_n;i++)        for(j=0;j<mat_n;j++)            a[i][j]=c[i][j];}void matrix_power(uint64 s[][mat_n],uint64 k,uint64 mod){    uint64 ans[mat_n][mat_n];    memset(ans,0,sizeof(ans));    int i,j;    for(i=0;i<mat_n;i++)        ans[i][i]=1;    while(k>0)    {        if(k%2==1) matrix_mul(ans,s,mod);        k=k/2;        matrix_mul(s,s,mod);    }    for(i=0;i<mat_n;i++)        for(j=0;j<mat_n;j++)            s[i][j]=ans[i][j];}int main(){    scanf("%I64d %I64d %I64d %I64d %I64d %I64d",&n,&sx,&sy,&dx,&dy,&t);    sx--; sy--;    fzc[0][0]=sx; fzc[1][0]=sy; fzc[2][0]=dx; fzc[3][0]=dy; fzc[4][0]=0; fzc[5][0]=1;    matrix_power(F,t,n);    matrix_mul(F,fzc,n);    printf("%I64d %I64d\n",(F[0][0]+n)%n+1,(F[1][0]+n)%n+1);    return 0;}


0 0
原创粉丝点击