2022.12.15 PM 09:30 by CBJ
來源 : https://zerojudge.tw/ShowProblem?problemid=f580 出題者 : 2020年7月APCS 標籤 : 模擬法、陣列操作、struct結構 難易度 : 3
解題想法 : 我們可以透過模擬骰子的方式完成題目,首先最重要的就是定義骰子要「長怎樣」,筆者使用的是骰子展開圖,並對每個面進行命名,以下提供兩種方式供讀者參考。 1. 結構法(見C/C++解) : 建立一個struct叫做dice如下: struct dice{ int top; int down; int front; int back; int left; int right; }; //記得分號!!! 表示成展開圖會像這樣 : __ __|__|__ __ back |__|__|__|__| ==> left top right down |__| front 2. 二維陣列法(見Python解) 定義一個二維陣列dices,dices的每個元素都是長度為6的陣列,代表骰子的6個面,圖示如下 : __ __|__|__ __ 1 |__|__|__|__| ==> 2 3 4 5 |__| 6 建dices的程式碼 : dices=[[-1]]+[[-1,3,5,1,2,6,4] for _ in range(n)] (由於每顆骰子是從1~n編號,所以需在dices的前面加上一個無意義的陣列(包括dices中的每個元素也是1-base,因此實際上dices是以每個大小皆為7的陣列組成,且第0項無意義(筆者習慣填入-1表示無意義))) 再來的數個操作只要在合適的定義下,都可以透過觀察輕鬆解決,而C語言的struct操作會比較繁瑣,讀者可以嘗試挑戰看看,或是使用較好操作的二維陣列法來實作即可。
//C language
/*
定義每個面的名稱
(平面展開圖)
back
left top right down
front
向右轉:
back
down left top right
front
向前轉:
down
left back right front
top
*/
#include<stdio.h>
typedef struct dice{
int top;
int down;
int front;
int back;
int left;
int right;
}dice;
dice dices[25];
void swap(dice* x,dice* y){
int tmp;
tmp=x->top; x->top=y->top; y->top=tmp;
tmp=x->down; x->down=y->down; y->down=tmp;
tmp=x->front; x->front=y->front; y->front=tmp;
tmp=x->back; x->back=y->back; y->back=tmp;
tmp=x->left; x->left=y->left; y->left=tmp;
tmp=x->right; x->right=y->right; y->right=tmp;
}
void turn_front(int a){
dice x = dices[a];
dices[a].top = x.back;
dices[a].down = x.front;
dices[a].front = x.top;
dices[a].back = x.down;
dices[a].left = x.left; //可省略
dices[a].right = x.right; //可省略
}
void turn_right(int a){
dice x = dices[a];
dices[a].top = x.left;
dices[a].down = x.right;
dices[a].front = x.front; //可省略
dices[a].back = x.back; //可省略
dices[a].left = x.down;
dices[a].right = x.top;
}
int main(){
int n,m,a,b;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
dice tmp = {1,6,4,3,5,2};
dices[i] = tmp;
}
while(m--){
scanf("%d%d",&a,&b);
if(b>0) swap(&dices[a],&dices[b]);
else{
if(b==-1) turn_front(a);
else turn_right(a);
}
}
for(int i=1;i<=n;i++) printf("%d ",dices[i].top);
printf("\n");
return 0;
}

//C++ language
/*
定義每個面的名稱
(平面展開圖)
back
left top right down
front
向右轉:
back
down left top right
front
向前轉:
down
left back right front
top
*/
#include<iostream>
#include<vector>
using namespace std;
struct dice{
int top;
int down;
int front;
int back;
int left;
int right;
};
vector<dice>dices(21,{1,6,4,3,5,2});
void turn_front(int a){
dice &x = dices[a];
x = {x.back,x.front,x.top,x.down,x.left,x.right};
}
void turn_right(int a){
dice &x = dices[a];
x = {x.left,x.right,x.front,x.back,x.down,x.top};
}
int main(){
int n,m,a,b;
cin>>n>>m;
while(m--){
cin>>a>>b;
if(b>0) swap(dices[a],dices[b]);
else{
if(b==-1) turn_front(a);
else turn_right(a);
}
}
for(int i=1;i<=n;i++) cout<<dices[i].top<<" ";
cout<<"\n";
return 0;
}

## Python language
## 初始狀態
## 1
## 2 3 4 5
## 6
## 3 6
## 5 1 2 6 ->front-> 5 3 2 4
## 4 1
##
## 3 3
## 5 1 2 6 ->right-> 6 5 1 2
## 4 4
n,m=map(int,input().split())
dices=[[-1]]+[[-1,3,5,1,2,6,4] for _ in range(n)]
def top(dice):
return dice[3]
def front(dice):
dice[1],dice[3],dice[6],dice[5]=dice[5],dice[1],dice[3],dice[6]
def right(dice):
dice[2],dice[3],dice[4],dice[5]=dice[5],dice[2],dice[3],dice[4]
for i in range(m):
a,b=map(int,input().split())
if b>0: dices[a],dices[b]=dices[b],dices[a]#swap(dices[a],dices[b])
elif b==-1: front(dices[a])
elif b==-2: right(dices[a])
for i in range(1,n+1):
print(top(dices[i]),end=' ')
print()
