广东汕头市队赛? 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; 
}
posted @ 2017-08-08 21:57  Brian551  阅读(199)  评论(0编辑  收藏  举报