2023.1.6 PM 07:30 by CBJ
來源 : https://zerojudge.tw/ShowProblem?problemid=b965 出題者 : 2016年3月APCS 標籤 : 陣列操作 難易度 : 2
解題想法 : 這題有個大家容易犯的小陷阱,題目敘述的範例是將A轉成B,而題目要求的是給予一個B,求出原始的A,因此我們實作的翻轉和旋轉不會是題目所敘的那樣操作,而會是完全相反。 實作上可以定義兩個函式flip()和rotate(),分別用來操作翻轉和旋轉。 首先觀察翻轉操作可以發現,當某個矩陣翻轉時,他的排列會變成倒著放,例如{{2,1}, {1,3}, {1,1}}經由翻轉後會變成{{1,1}, {1,3}, {2,1}},剛好就是reverse的結果,可以使用內建函式或for i,j完成。 再來是旋轉,我們可以透過追蹤每個點所會對應到的位置來進行分析,發現 (第一行,第一列)會跑到(第一行,倒數第一列), (第二行,第一列)會跑到(第一行,倒數第二列), (第一行,第二列)會跑到(第二行,倒數第一列), 經由分析,我們可以看到 (第i行,第j列)的值會跑到(第j行,倒數第i行),因此我們只要跑兩層迴圈讓 i 從 0~行數,j 從 0~列數,並將新矩陣(j,倒數第i)的值設為矩陣(i,j)的值即可,但由於計算倒數十分的麻煩,因此我們可以進一步發現到,將第n行變成倒數第n行其實就是flip()在做的事,因此我們只要將新矩陣(j,i)的值先設為矩陣(i,j)的值,最後再呼叫flip()將新矩陣(j,i)翻轉成(j,倒數第i)即可。 (因此flip()要定義在rotate()之上,才可以被呼叫) ※注意,題目要求嚴格比對,因此輸出的每行後面不能有空白。
// C language
#include<stdio.h>
int R,C,M;
int ok; //1: R,C 0: C,R
int matrix[15][15];
void swap(int* a,int* b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void flip(int R,int C){
int tmp[15][15];
for(int i=0,j=R-1; j>=0; i++,j--){
for(int k=0;k<C;k++){
tmp[i][k]=matrix[j][k];
}
}
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
matrix[i][j]=tmp[i][j];
}
}
}
void rotate(int R,int C){
int tmp[15][15];
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
tmp[j][i] = matrix[i][j];
}
}
for(int i=0;i<C;i++){
for(int j=0;j<R;j++){
matrix[i][j]=tmp[i][j];
}
}
flip(C,R);
ok = !ok;
}
int main(){
while(scanf("%d%d%d",&R,&C,&M)!=EOF){
ok=1;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
scanf("%d",&matrix[i][j]);
}
}
int operates[15];
for(int i=0;i<M;i++){
scanf("%d",&operates[i]);
}
for(int i=0,j=M-1; i<j; i++,j--){
swap(&operates[i],&operates[j]);
}
for(int i=0;i<M;i++){
if(!operates[i]){
if(ok) rotate(R,C);
else rotate(C,R);
}
else{
if(ok) flip(R,C);
else flip(C,R);
}
}
if(ok){
printf("%d %d\n",R,C);
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(j==(C-1)) printf("%d",matrix[i][j]);
else printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
else{
printf("%d %d\n",C,R);
for(int i=0;i<C;i++){
for(int j=0;j<R;j++){
if(j==(R-1)) printf("%d",matrix[i][j]);
else printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
}
return 0;
}

//C++ language
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<vector<int>>matrix;
void flip(){reverse(matrix.begin(),matrix.end());}
void rotate(){
vector<vector<int>>tmp;
for(int i=0;i<matrix[0].size();i++){
vector<int>combine;
for(int j=0;j<matrix.size();j++) combine.push_back(matrix[j][i]);
tmp.push_back(combine);
}
matrix=tmp;
flip();
}
int main(){
int R,C,M;
while(cin>>R>>C>>M){
matrix.clear();
for(int i=0;i<R;i++){
vector<int>tmp;
for(int i=0;i<C;i++){
int x; cin>>x;
tmp.push_back(x);
}
matrix.push_back(tmp);
}
vector<bool>operates;
while(M--){
bool x; cin>>x;
operates.push_back(x);
}
reverse(operates.begin(),operates.end());
for(bool b:operates){
if(!b) rotate();
else flip();
}
cout<<matrix.size()<<" "<<matrix[0].size()<<"\n";
for(vector<int> v:matrix) for(int i=0;i<v.size();i++) cout<<v[i]<<(" \n"[i==v.size()-1]);
}
return 0;
}

## Python language
from sys import stdin
def flip(matrix):
return list(reversed(matrix))
def rotate(matrix):
tmp=[]
row=len(matrix)
col=len(matrix[0])
for i in range(col):
combine=[]
for j in range(row):
combine.append(matrix[j][i])
tmp.append(combine)
return list(reversed(tmp))
for read in stdin:
R,C,M=map(int,read.rstrip().split())
matrix=[]
for i in range(R): matrix.append([int(x) for x in input().split()])
operates=[int(x) for x in input().split()]
for i in list(reversed(operates)):
if i==0: matrix=rotate(matrix)
elif i==1: matrix=flip(matrix)
print(len(matrix),len(matrix[0]))
for i in matrix: print(*i,sep=' ')
