先上题目
题目描述
给出一个R行C列的空白表格,在表格的左上方第一个格子处放了一枚骰子。骰子有六个面,分别有1,2,3,4,5,6这六个数字,其中,相反两面的数之和为7.骰子初始的时候是这样放置的,上面为1,右侧那一面为3。现在将骰子进行下面4种操作:
1.往右滚动,直到达到最后一列。
2.往下滚动,达到下一行
3.往左滚动,直到达到第一列。
4.往下滚动,到达到下一行。
现在你按照上面的4种操作,依次进行,直到将所有格子都走一遍。每走到一个格子上,将骰子最上方那面的数字记下来。最后,求出所有记下来的数字之和。
输入
输入:
两个整数R,C.(R,C均为小于100000的正整数)
输出
输出:
所有数字之和。
50%的数据,R,C均小于100.
样例输入
样例输出
今天,在一次比赛中看见了这道题。最开始拿到题,我就想到去打表(⊙﹏⊙b汗),后来发现这太不科学了,一定是有归律可循的,但想不出来,后来和某某交谈后才恍然大悟,写出了这道题,可过样例后,在OJ 2214上仍然没过,不对。后来发现要开long long int,之后顺利通过。
这道题其实实质上是一道模拟的问题,通过把列数压缩到4以内在进行模拟就是正解。
这道题我用了三个整形保存上,前,下三面的值,不断滚动骰子,最后得出结论。
代码
#include<cstdio>
using namespace std;
long long r,c,ans;//分别表示输入的r行c列及答案
int main()
{
scanf("%lld%lld",&r,&c);
bool dir=true;//标记是向左还是向右
int up=1,front=2,right=3;//表示骰子上方前面和右边
int u;//用于临时保存原来的值
for (int i=1; i<=r; ++i)
{
if(dir)//从左往右
{
ans+=c/4*14;
for(int j=c/4*4+1; j<=c; ++j)
{
ans+=up;
u=up;
if(j<c)up=7-right,right=u;//如果没到最后一个,最上面就变成左边的。
else up=7-front,front=u;//向下一个
}
dir=!dir;
}
else{//同上,只是滚动骰子的方法有小变化,从右到左的方向滚动。
ans+=c/4*14;
for(int j=c-c/4*4; j>=1; --j)
{
ans+=up;
u=up;
if (j>1) up = right, right = 7-u;
else up = 7-front, front = u;
}
dir = !dir;
}
}
printf("%lld",ans);
}