• 广东汕头市队赛? T1 模拟


    骰子

    (dice.pas/c/cpp) 1s 128MB

    骰子。骰子就是很普通的骰子:骰子有六个面,分别标号1到6,三对面上的数字之和均为7。

    游戏的地图:一个高为R宽为C的网格图。

    骰子一开始的状态如上图所示(即上面为1,下面为6,左面为4,右面为3,前面为2,后面为5),且位置在左上角。

    你需要的操作就是滚动骰子。你需要向右滚动到最右端,然后向下滚动一格然后在向左滚动到最左端,再向下一格,如此反复…直到最下面一行的所有格都被滚过为止。

    游戏的目的就是请你计算出骰子到达每个格点时,骰子上方的数字之和。

    输入格式

    也就含两个整数R和C。

    输出格式

    也就一个数字,表示骰子上方之和。

    样例1输入

    3 2

    样例1输出

    19

    样例2输入

    3 4

    样例2输出

    42

    数据范围

    30%:1<=R,C<=1,000

    60%:1<=R,C<=1,000,000

    100%:1<=R,C<=1,000,000,000


    这题有点诡异

    一般遇到这种找规律的

    都习惯手算找规律

    于是我自己做了个骰子。。

    模拟了半天

    十分的混乱。。

    结果正解是让计算机找规律

    找重复出现的循环节。。

    长知识了。。。。

    这道题细节处理比较多。。。

    首先横向的可以直接%4

    这样就能拿到60分。。。

    然后研究竖向的

    应该也是有循环的。。。

    所以要先模拟求出循环节。。

    处理起来其实有点麻烦。。

    然后注意即使sum是longlong

    如果sum+=a*b

    并且a*b爆int的话

    还是会炸的

    所以要先转ll。。。

    #include<cstdio>
    #include<cstring>
    #include<queue>
    struct node
    {
    	int qian,hou,zuo,you,shang,xia;
    }e;
    void xia()
    {
    	int q=e.qian;
    	e.qian=e.shang;
    	e.shang=e.hou;
    	e.hou=e.xia;
    	e.xia=q;
    }
    void zuo()
    {
    	int q=e.zuo;
    	e.zuo=e.shang;
    	e.shang=e.you;
    	e.you=e.xia;
    	e.xia=q;
    }
    void you()
    {
    	int q=e.zuo;
    	e.zuo=e.xia;
    	e.xia=e.you;
    	e.you=e.shang;
    	e.shang=q;
    }
    void init()
    {
    	e.shang=1;		e.xia=6;
    	e.zuo=4;		e.you=3,
    	e.qian=2;		e.hou=5;
    }
    bool check(node a,node b)
    {
    	if(a.qian==b.qian&&b.hou==a.hou&&a.zuo==b.zuo&&a.you==b.you&&a.shang==b.shang&&a.xia==b.xia)	return 1;
    	return 0;
    }
    std::queue<node> qu;
    int main()
    {
    	freopen("dice.in","r",stdin);		
    	freopen("dice.out","w",stdout);
    	int n,m;
    	scanf("%d %d",&n,&m);
    	init();
    	long long sum=e.shang;
    	long long int tt=(m-1)>>2,kk=(m-1)&3;
    	long long xunhuan;
    	int xx=-1;
    	for(int i=1;i<=n;i++)
    	{
    		if(i&1)	
    		{
    			qu.push((node){e.qian,e.hou,e.zuo,e.you,e.shang,e.xia});
    			if(qu.size()!=1&&check(qu.front(),qu.back())==1)			
    			{
    				xunhuan=sum-1;
    				xx=i-1;
    				break;
    			}
    		}
    		sum+=14*tt;
    		if(i&1)	
    		for(int j=1;j<=kk;j++)	you(),sum+=e.shang;
    		else 
    		for(int j=1;j<=kk;j++)	zuo(),sum+=e.shang;
    		if(i!=n) xia(),sum+=e.shang;
    	}
    	
    	long long kn,tn;
    	if(xx!=-1)
    	{
    		tn=n/xx,kn=n%xx,sum=tn*xunhuan;
    		sum+=1;
    		if(kn==0)	sum-=e.shang;
    	}
    	else 
    	{
    		init();
    		sum=e.shang;
    		kn=n;
    	}
    	tt=(m-1)>>2,kk=(m-1)&3;
    	for(int i=1;i<=kn;i++)
    	{
    		sum+=14*tt;
    		if(i&1)	
    		for(int j=1;j<=kk;j++)	you(),sum+=e.shang;
    		else 
    		for(int j=1;j<=kk;j++)	zuo(),sum+=e.shang;
    		if(i!=kn) xia(),sum+=e.shang;
    	}
    
    	printf("%lld",sum);
    	fclose(stdin);
    	fclose(stdout);
    	return 0; 
    }
  • 相关阅读:
    iconv 文件编码转换
    source insight 中文注释为乱码解决
    c: c代码书写规范
    Ubuntu: 搭建tftp,nfs服务器
    Linux: 信息查看
    liteos时间管理(九)
    最大连续子数列和
    递归为什么那么慢?递归的改进算法
    liteos信号量(八)
    liteos互斥锁(七)
  • 原文地址:https://www.cnblogs.com/Brian551/p/7352994.html
Copyright © 2020-2023  润新知