【2012年中山纪念中学信息学竞赛初一选拔赛一】纪中游戏(d)
【2012年中山纪念中学信息学竞赛初一选拔赛一】纪中游戏(d)
(File IO): input:d.in output:d.out 时间限制: 1000 ms 空间限制: 262144 KB
【题目描述】
纪中的学生是很幸福的,因为纪中有很多课外活动,每一个学生都能找到施展才华的舞台。除了上面说的JBA外,每年还有元旦晚会、主持人大赛、形象大使、街舞比赛、心声晚会、每周一演等等很多活动。
最近纪中又推出一项益智类的游戏——玩骰子,骰子是一个立方体,数字1到6分布在6个面上(如图所示),而且对着的两个面上的数字之和等于7,也就是说6对着1,5对着2,4对着3。
一开始骰子被放在一个R*C的棋盘的左上角格子上,骰子一开始的状态是:数字1在上面,1的右边是3,同样为上图所示(即上面为1,下面为6,左面为4,右面为3,前面为2,后面为5)。
现在允许你进行以下操作:把骰子往右滚直到到达最后一列,然后把骰子往下滚到达下一行,再把骰子往左滚直到碰到第一列,然后把骰子往下滚到达下一行,再把骰子往右滚直到碰到最后一列,再把骰子往下滚到达下一行。。。,如此反复下去直到所有的格子都经过一次。
要求计算到达所有格子时上面数字之和。
【输入】
第一行包含两个整数R和C(1<=R,C<=100,000)
【输出】
计算到达所有格子时上面数字之和。
【样例输入】
样例输入1
3 2
样例输入2
3 4
样例输入3
737 296
【样例输出】
样例输出1
19
样例输出2
42
样例输出3
763532
【数据范围限制】
50%的数据满足:1<=R,C<=100。
【提示】
样例1经过每个格子时骰子上面的数字依次为:1 4 5 1 3 5。
【思路】
用一个变量t[]来模拟每个格子当前是多少,接着去循环每一
行。如[1]=1,[2]=6,[3]=2,[4]=5,[5]=4,[6]=3
用双重循环来模拟,每滚一步,就判断i是否是奇数,如果是,就int tmp=a[0]; a[0]=a[4]; a[4]=a[1]; a[1]=a[5]; a[5]=tmp;
否则就int tmp=a[0]; a[0]=a[5]; a[5]=a[1]; a[1]=a[4]; a[4]=tmp;
,最后答案加上上面的
数。但还要竖着往下滚一次,同样,就int tp=a[0]; a[0]=a[3]; a[3]=a[1]; a[1]=a[2]; a[2]=tp;
,最后输出答案。(这个规律大家拿个骰子滚一滚试一试也能发现)
看到这里,如果你打个代码试一试就会发现会超时!!!(哦对了还有记得用long long,否则你懂的!)
我们可以发现,这其实有重复的周期,每翻四次的和就是十四(具体大家自己思考)。所以我们可以进行优化,用此公式:ans+=(a[1]+a[2]+a[3]+a[4])*(c/4);
这样循环就可以减少很多次计算,从1~c%4就可以了。剩下部
分就和之前的一样了。
【AC代码】
1️⃣
#include<cstdio>
using namespace std;
long long r,c,t,ans = 0;
int a[6] = {1,6,2,5,4,3}; //上 下 前 后 右 左
void roll_right(){
int tmp = a[0];
a[0] = a[4];
a[4] = a[1];
a[1] = a[5];
a[5] = tmp;
}
void roll_left(){
int tmp = a[0];
a[0] = a[5];
a[5] = a[1];
a[1] = a[4];
a[4] = tmp;
}
void roll_down(){
int tmp = a[0];
a[0] = a[3];
a[3] = a[1];
a[1] = a[2];
a[2] = tmp;
}
int main()
{
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%lld%lld",&r,&c); //n行m列
c--; //骰子所在的位置不需要滚动,需要滚动的次数为c-1
for(int i = 1;i <= r;++i){
ans += a[0];
t = c / 4; //能滚多少次循环
ans += (a[0] + a[1] + a[2] + a[3]) * t;
if(i % 2 == 1){ //当前在奇数行,向右滚
for(int j = 1;j <= c % 4;++j){
roll_right();
ans += a[0];
}
}
else{ //当前在偶数行,向左滚
for(int j = 1;j <= c % 4;++j){
roll_left();
ans += a[0];
}
}
roll_down(); //向下滚到下一行
}
printf("%lld",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
2️⃣
#include<iostream>
#include<cstdio>
using namespace std;
int a[]={1,6,2,5,4,3};
long long ans,t;
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
int r,c;
cin>>r>>c;
c--;
for(int i=1;i<=r;i++){
ans+=a[0];
t=c/4;
ans+=(a[0]+a[1]+a[2]+a[3])*t;
if(i%2==1){
for(int j=1;j<=c%4;j++){
int tmp=a[0];
a[0]=a[4];
a[4]=a[1];
a[1]=a[5];
a[5]=tmp;
ans+=a[0];
}
}else{
for(int j=1;j<=c%4;j++){
int tmp=a[0];
a[0]=a[5];
a[5]=a[1];
a[1]=a[4];
a[4]=tmp;
ans+=a[0];
}
}
int tp=a[0];
a[0]=a[3];
a[3]=a[1];
a[1]=a[2];
a[2]=tp;
}
cout<<ans;
fclose(stdin);
fclose(stdout);
}
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!