f580: 2. 骰子

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()

相關文章