T11 圖像旋轉
描述
輸入一個n行m列的黑白圖像,將它順時針旋轉90度后輸出。
輸入
第一行包含兩個整數n和m,表示圖像包含像素點的行數和列數。1 <= n <= 100,1 <= m <= 100。
接下來n行,每行m個整數,表示圖像的每個像素點灰度。相鄰兩個整數之間用單個空格隔開,每個元素均在0~255之間。
輸出
m行,每行n個整數,為順時針旋轉90度后的圖像。相鄰兩個整數之間用單個空格隔開。

樣例輸入 3 3 1 2 3 4 5 6 7 8 9 樣例輸出 7 4 1 8 5 2 9 6 3
以矩陣元素坐標為例:
1,1 1,2 1,3 順時針旋轉后為 2,1 1,1
2,1 2,2 2,3 2,2 1,2
2,3 1,3
所以輸出時第一重循環i正着循環每一列,第二重循環j倒着循環每一行,依次輸出(j,i)

1 #include<iostream> 2 using namespace std; 3 int n,m,a[101][101]; 4 int main() 5 { 6 cin>>n>>m; 7 for(int i=1;i<=n;i++) 8 for(int j=1;j<=m;j++) 9 cin>>a[i][j]; 10 for(int i=1;i<=m;i++) 11 { 12 for(int j=n;j>=1;j--) 13 cout<<a[j][i]<<' '; 14 cout<<endl; 15 } 16 }
T12 變換的矩陣
描述
有一個N x N(N為奇數,且1 <= N <= 10)的矩陣,矩陣中的元素都是字符。這個矩陣可能會按照如下的幾種變幻法則之一進行變幻(只會變幻一次)。
現在給出一個原始的矩陣,和一個變幻后的矩陣,請編寫一個程序,來判定原始矩陣是按照哪一種法則變幻為目標矩陣的。
1. 按照順時針方向旋轉90度;
如:
1 2 3 7 4 1
4 5 6 變幻為 8 5 2
7 8 9 9 6 3
2. 按照逆時針方向旋轉90度;
如:
1 2 3 3 6 9
4 5 6 變幻為 2 5 8
7 8 9 1 4 7
3. 中央元素不變(如下例中的 5),其他元素(如下例中的3)與“以中央元素為中心的對應元素”(如下例中的7)互換;
如:
1 2 3 9 8 7
4 5 6 變幻為 6 5 4
7 8 9 3 2 1
4. 保持原始矩陣,不變幻;
5. 如果 從原始矩陣 到 目標矩陣 的變幻,不符合任何上述變幻,請輸出5
輸入
第一行:矩陣每行/列元素的個數 N;
第二行到第N+1行:原始矩陣,共N行,每行N個字符;
第N+2行到第2*N+1行:目標矩陣,共N行,每行N個字符;
輸出
只有一行,從原始矩陣 到 目標矩陣 的所采取的 變幻法則的編號。

樣例輸入 5 a b c d e f g h i j k l m n o p q r s t u v w x y y x w v u t s r q p o n m l k j i h g f e d c b a 樣例輸出 3
方法1(比較麻煩,但是快用時1ms,時間復雜度n²—4n²):記錄下原始矩陣每一種變換情況后的矩陣,然后與目標矩陣對比
1,1 1,2 1,3 順時針旋轉后為 2,1 1,1
2,1 2,2 2,3 2,2 1,2
2,3 1,3
所以記錄時第一重循環i正着循環每一列,第二重循環j倒着循環每一行,依次記錄a[j][i]
1,1 1,2 1,3 逆時針旋轉后為 1,3 2,3
2,1 2,2 2,3 1,2 2,2
1,1 2,1
所以記錄時第一重循環i正着循環每一行,第二重循環j倒着循環每一列,依次記錄a[i][j]
情況3也就是將整個矩陣旋轉180°,所以記錄時兩重循環都倒着循環

1 #include<iostream> 2 #include<cstdlib> 3 using namespace std; 4 int n; 5 char a[11][11],b[11][11],c[11][11]; 6 void case1() 7 { 8 int x=0,y=0; 9 for(int i=1;i<=n;i++) 10 { 11 x++;y=0; 12 for(int j=n;j>=1;j--) 13 c[x][++y]=a[j][i]; 14 for(int k=1;k<=n;k++) 15 if(c[x][k]!=b[x][k]) 16 return; 17 } 18 cout<<'1'; 19 exit(0); 20 } 21 void case2() 22 { 23 int x=0,y=0; 24 for(int i=n;i>=1;i--) 25 { 26 x++;y=0; 27 for(int j=1;j<=n;j++) 28 c[x][++y]=a[j][i]; 29 for(int k=1;k<=n;k++) 30 if(c[x][k]!=b[x][k]) 31 return ; 32 } 33 cout<<'2'; 34 exit(0); 35 } 36 void case3() 37 { 38 int x=0,y=0; 39 for(int i=n;i>=1;i--) 40 { 41 x++;y=0; 42 for(int j=n;j>=1;j--) 43 c[x][++y]=a[i][j]; 44 for(int k=1;k<=n;k++) 45 if(c[x][k]!=b[x][k]) 46 return; 47 } 48 cout<<'3'; 49 exit(0); 50 } 51 void case4() 52 { 53 for(int i=1;i<=n;i++) 54 for(int j=1;j<=n;j++) 55 if(a[i][j]!=b[i][j]) 56 return; 57 cout<<'4'; 58 exit(0); 59 } 60 int main() 61 { 62 cin>>n; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++) 65 cin>>a[i][j]; 66 for(int i=1;i<=n;i++) 67 for(int j=1;j<=n;j++) 68 cin>>b[i][j]; 69 case1(); 70 case2(); 71 case3(); 72 case4(); 73 cout<<'5'; 74 return 0; 75 }
方法2(代碼較短,但慢一點,9ms,時間復雜度,固定4n²):
省去方法1中的記錄,直接根據目標矩陣與原矩陣變換后元素的位置關系判斷。所以需要判斷完所有位置才能出結果
順時針旋轉目標數組b[i][j]對應原數組a[n-j+1][i]
逆時針旋轉目標數組b[i][j]對應原數組a[j][n-i+1]
中心對稱目標數組b[i][j]對應原數組a[n-i+1][n-j+1]

1 #include<iostream> 2 using namespace std; 3 int n; 4 char a[101][101],b[101][101]; 5 bool p[5]; 6 int main() 7 { 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 for(int j=1;j<=n;j++) 11 cin>>a[i][j]; 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 cin>>b[i][j]; 15 for(int i=1;i<=n;i++) 16 for(int j=1;j<=n;j++) 17 { 18 if(b[i][j]!=a[n-j+1][i]) p[1]=true; 19 if(b[i][j]!=a[j][n-i+1]) p[2]=true; 20 if(b[i][j]!=a[n-i+1][n-j+1]) p[3]=true; 21 if(b[i][j]!=a[i][j]) p[4]=true; 22 } 23 for(int i=1;i<=4;i++) 24 if(!p[i]) 25 { 26 cout<<i;return 0; 27 } 28 cout<<'5'; 29 }
T13 圖像模糊處理
描述
給定n行m列的圖像各像素點的灰度值,要求用如下方法對其進行模糊化處理:
1. 四周最外側的像素點灰度值不變;
2. 中間各像素點新灰度值為該像素點及其上下左右相鄰四個像素點原灰度值的平均(舍入到最接近的整數)。
輸入
第一行包含兩個整數n和m,表示圖像包含像素點的行數和列數。1 <= n <= 100,1 <= m <= 100。
接下來n行,每行m個整數,表示圖像的每個像素點灰度。相鄰兩個整數之間用單個空格隔開,每個元素均在0~255之間。
輸出
n行,每行m個整數,為模糊處理后的圖像。相鄰兩個整數之間用單個空格隔開。

樣例輸入 4 5 100 0 100 0 50 50 100 200 0 0 50 50 100 100 200 100 100 50 50 100 樣例輸出 100 0 100 0 50 50 80 100 60 0 50 80 100 90 200 100 100 50 50 100
四舍五入可以用函數round,也可以用printf(”.0lf“,x);

1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 int n,m,a[101][101],b[101][101]; 5 int main() 6 { 7 cin>>n>>m; 8 for(int i=1;i<=n;i++) 9 for(int j=1;j<=m;j++) 10 cin>>a[i][j]; 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=m;j++) 13 { 14 if(i==1||i==n||j==1||j==m) 15 b[i][j]=a[i][j]; 16 else 17 { 18 double r=((double)a[i][j]+a[i-1][j]+a[i+1][j]+a[i][j-1]+a[i][j+1])/5; 19 b[i][j]=round(r); 20 } 21 } 22 for(int i=1;i<=n;i++) 23 { 24 for(int j=1;j<=m;j++) 25 cout<<b[i][j]<<' '; 26 cout<<endl; 27 } 28 }
T14 掃雷游戲地雷數計算
描述
掃雷游戲是一款十分經典的單機小游戲。它的精髓在於,通過已翻開格子所提示的周圍格地雷數,來判斷未翻開格子里是否是地雷。
現在給出n行m列的雷區中的地雷分布,要求計算出每個非地雷格的周圍格地雷數。
注:每個格子周圍格有八個:上、下、左、右、左上、右上、左下、右下。
輸入
第一行包含兩個整數n和m,分別表示雷區的行數和列數。1 <= n <= 100, 1 <= m <= 100。
接下來n行,每行m個字符,‘*’表示相應格子中是地雷,‘?’表示相應格子中無地雷。字符之間無任何分隔符。
輸出
n行,每行m個字符,描述整個雷區。若相應格中是地雷,則用‘*’表示,否則用相應的周圍格地雷數表示。字符之間無任何分隔符。

樣例輸入 3 3 *?? ??? ?*? 樣例輸出 *10 221 1*1
兩種思路:1、統計出每個地雷的位置,以地雷為基准,周圍8個非地雷的格子+1。預測應該比第二種方法快
2、以每一個格子為基准,枚舉周圍8個格子。時間復雜度O(8n²)
在此只提供第一種方法的代碼

1 #include<iostream> 2 using namespace std; 3 int n,m,b[101][101],cnt; 4 int dx[8]={-1,-1,-1,0,1,1,1,0}; 5 int dy[8]={-1,0,1,1,1,0,-1,-1}; 6 int x[10001],y[10001]; 7 char a[101][101]; 8 int main() 9 { 10 cin>>n>>m; 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=m;j++) 13 { 14 cin>>a[i][j]; 15 if(a[i][j]=='*') 16 { 17 x[++cnt]=i;y[cnt]=j; 18 } 19 } 20 for(int i=1;i<=cnt;i++) 21 { 22 int xx=x[i],yy=y[i]; 23 for(int j=0;j<8;j++) 24 { 25 int nx=xx+dx[j],ny=yy+dy[j]; 26 if(nx>0&&nx<=n&&ny>0&&ny<=m&&a[nx][ny]!='*') 27 b[nx][ny]++; 28 } 29 } 30 for(int i=1;i<=n;i++) 31 { 32 for(int j=1;j<=m;j++) 33 if(a[i][j]=='*') cout<<'*'; 34 else cout<<b[i][j]; 35 cout<<endl; 36 } 37 }
T15 細菌的繁殖與擴散
描述
在邊長為9的正方形培養皿中,正中心位置有m個細菌。假設細菌的壽命僅一天,但每天可繁殖10個后代,而且這10個后代,有兩個分布在原來的單元格中,其余的均勻分布在其四周相鄰的八個單元格中。求經過n(1≤n≤4)天后,細菌在培養皿中的分布情況。
輸入
輸入為兩個整數,第一個整數m表示中心位置細菌的個數(2 ≤ m ≤ 30),第二個整數n表示經過的天數(1 ≤ n ≤ 4)。
輸出
輸出九行九列整數矩陣,每行的整數之間用空格分隔。整個矩陣代表n天后細菌在培養皿上的分布情況。

樣例輸入 2 1 樣例輸出 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 2 4 2 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
三維數組a[k][i][j]代表第k天后矩陣[i,j]位置的細菌數,每次更新時,由於細菌壽命只有一天,所以新的a[k][i][j]=a[k-1][i][j]*2+a[k-1][ni][nj],ni,nj為[i,j]周圍的八個單元格

1 #include<iostream> 2 using namespace std; 3 int m,n; 4 int dx[8]={-1,-1,-1,0,1,1,1,0}; 5 int dy[8]={-1,0,1,1,1,0,-1,-1}; 6 int a[5][10][10]; 7 int main() 8 { 9 cin>>m>>n; 10 a[0][5][5]=m; 11 for(int k=1;k<=n;k++)//枚舉每一天 12 { 13 for(int i=1;i<=9;i++) 14 for(int j=1;j<=9;j++)//枚舉每個單元格 15 { 16 a[k][i][j]=2*a[k-1][i][j];//留在原單元格的2個 17 for(int l=0;l<8;l++)//周圍的8個單元格 18 { 19 int nx=i+dx[l],ny=j+dy[l]; 20 if(nx>0&&nx<=9&&ny>0&&ny<=9) 21 a[k][i][j]+=a[k-1][nx][ny]; 22 } 23 } 24 } 25 for(int i=1;i<=9;i++) 26 { 27 for(int j=1;j<=9;j++) 28 cout<<a[n][i][j]<<' '; 29 cout<<endl; 30 } 31 }
上面的代碼是9ms,下面這個是0ms,搞不懂哪里拖延了時間,期待各位的指點

1 #include<bits/stdc++.h> 2 using namespace std; 3 int G[15][15],m,n,a[15][15],dx[]={0,0,1,-1,1,-1,1,-1},dy[]={-1,1,0,0,1,-1,-1,1}; 4 int main() 5 { 6 cin>>m>>n;G[5][5]=m; 7 while(n--) 8 { 9 memset(a,0,sizeof(a)); 10 for(int i=1;i<=9;i++) 11 for(int j=1;j<=9;j++) 12 { 13 a[i][j]+=G[i][j]*2; 14 for(int k=0;k<8;k++) 15 a[i+dx[k]][j+dy[k]]+=G[i][j]; 16 } 17 memcpy(G,a,sizeof(a)); 18 } 19 for(int i=1;i<=9;i++) 20 { 21 for(int j=1;j<=9;j++) 22 cout<<G[i][j]<<' '; 23 cout<<endl; 24 } 25 return 0; 26 }
T16 矩陣石頭剪刀布
描述
Bart的妹妹Lisa在一個二維矩陣上創造了新的文明。矩陣上每個位置被三種生命形式之一占據:石頭,剪刀,布。每天,上下左右相鄰的不同生命形式將會發生戰斗。在戰斗中,石頭永遠勝剪刀,剪刀永遠勝布,布永遠勝石頭。每一天結束之后,敗者的領地將被勝者占領。
你的工作是計算出n天之后矩陣的占據情況。
輸入
第一行包含三個正整數r,c,n,分別表示矩陣的行數、列數以及天數。每個整數均不超過100。
接下來r行,每行c個字符,描述矩陣初始時被占據的情況。每個位置上的字符只能是R,S,P三者之一,分別代表石頭,剪刀,布。相鄰字符之間無空格。
輸出
輸出n天之后的矩陣占據情況。每個位置上的字符只能是R,S,P三者之一,相鄰字符之間無空格。

樣例輸入 3 3 1 RRR RSR RRR 樣例輸出 RRR RRR RRR
a[k][i][j]代表第k天,矩陣[i,j]的字符
枚舉每一天每一對格子的情況,因為它只會被能夠贏它的字符更新,且能更新它的字符只有一個,所以可以每次在四周找能更新它的字符,找到更新,找不到就保持原狀
因為R,S,P互相都有勝負關系,所以每一天每個格子只能被更新一次,所以更新了可以立刻停止對這個格子四周的搜索。例:R遇到P,R在今天結束時更新成P,但今天這個格子遇到R,平局,遇到S,勝利,自己不會被更新
所以確定a[k][i][j]時,要由a[k-1][i-1][j],a[k-1][i][j+1],a[k-1][i+1][j],a[k-1][i][j-1]決定,注意是k-1,即上一天的情況。例:PRS,P可以更新R,R可以更新S,由於枚舉的順序,所以先變成PPS,然后枚舉到S時,因為這還是同一天,所以要用原來的R來更新S,而不是用S來更新P
由於a[k][i][j]的情況只與a[k-1][][]有關,所以可以用滾動數組優化空間

1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int r,c,n; 5 int dx[4]={-1,0,1,0}; 6 int dy[4]={0,1,0,-1}; 7 char a[2][110][110]; 8 void work(int last/*滾動數組*/,int h/*行*/,int l/*列*/,char win/*目標字符,即可以更新它的字符*/) 9 { 10 int now=(last+1)%2; 11 int ok=0; 12 for(int i=0;i<4;i++) 13 { 14 if(a[last][h+dx[i]][l+dy[i]]==win) ok=1,a[now][h][l]=win; 15 if(ok) break;//更新了便可退出 16 } 17 if(!ok) a[now][h][l]=a[last][h][l]; 18 } 19 int main() 20 { 21 cin>>r>>c>>n; 22 for(int i=1;i<=r;i++) 23 for(int j=1;j<=c;j++) 24 cin>>a[0][i][j]; 25 for(int k=1;k<=n;k++) 26 { 27 memset(a[k%2],'\0',sizeof(a[k%2]));//滾動數組要初始化 28 for(int i=1;i<=r;i++) 29 for(int j=1;j<=c;j++) 30 switch(a[(k-1)%2][i][j]) 31 { 32 case 'R':work((k-1)%2,i,j,'P');break;//解釋:若這個格子為R,那要以這個格子的坐標為基准,在四周找能更新它的P 33 case 'S':work((k-1)%2,i,j,'R');break; 34 case 'P':work((k-1)%2,i,j,'S');break; 35 } 36 } 37 for(int i=1;i<=r;i++) 38 { 39 for(int j=1;j<=c;j++) 40 cout<<a[n&1][i][j]; 41 cout<<endl; 42 } 43 }
起初滾動數組的更新誤放到了work函數里,應該在這一天還未開始時清空掉上兩天的數據,即每天更新一次,放在work函數里成了每枚舉一個格子更新一次
T17 最好的草
描述
奶牛Bessie計划好好享受柔軟的春季新草。新草分布在R行C列的牧場里。它想計算一下牧場中的草叢數量。
在牧場地圖中,每個草叢要么是單個“#”,要么是有公共邊的相鄰兩個“#”。給定牧場地圖,計算有多少個草叢。
例如,考慮如下5行6列的牧場地圖
.#....
..#...
..#..#
...##.
.#....
這個牧場有5個草叢:一個在第一行,一個在第二列橫跨了二、三行,一個在第三行,一個在第四行橫跨了四、五列,最后一個在第五行。
輸入
第一行包含兩個整數R和C,中間用單個空格隔開。
接下來R行,每行C個字符,描述牧場地圖。字符只有“#”或“.”兩種。
輸出
輸出一個整數,表示草叢數。

樣例輸入 5 6 .#.... ..#... ..#..# ...##. .#.... 樣例輸出 5
裸的dfs搜索題,注意別忘了判重

1 #include<iostream> 2 using namespace std; 3 int r,c; 4 int dx[4]={-1,0,1,0}; 5 int dy[4]={0,1,0,-1}; 6 char a[101][101]; 7 bool v[101][101]; 8 int s; 9 void dfs(int x,int y) 10 { 11 for(int i=0;i<4;i++) 12 { 13 int nx=x+dx[i],ny=y+dy[i]; 14 if(nx>0&&nx<=r&&ny>0&&ny<=c&&a[nx][ny]=='#'&&!v[nx][ny]) 15 { 16 v[nx][ny]=true; 17 dfs(nx,ny); 18 } 19 } 20 } 21 int main() 22 { 23 cin>>r>>c; 24 for(int i=1;i<=r;i++) 25 for(int j=1;j<=c;j++) 26 cin>>a[i][j]; 27 for(int i=1;i<=r;i++) 28 for(int j=1;j<=c;j++) 29 if(a[i][j]=='#'&&!v[i][j]) 30 { 31 v[i][j]=true; 32 dfs(i,j); 33 s++; 34 } 35 cout<<s; 36 }
T18 腫瘤面積
描述
在一個正方形的灰度圖片上,腫瘤是一塊矩形的區域,腫瘤的邊緣所在的像素點在圖片中用0表示。其它腫瘤內和腫瘤外的點都用255表示。現在要求你編寫一個程序,計算腫瘤內部的像素點的個數(不包括腫瘤邊緣上的點)。已知腫瘤的邊緣平行於圖像的邊緣。
輸入
只有一個測試樣例。第一行有一個整數n,表示正方形圖像的邊長。其后n行每行有n個整數,取值為0或255。整數之間用一個空格隔開。已知n不大於1000。
輸出
輸出一行,該行包含一個整數,為要求的腫瘤內的像素點的個數。

樣例輸入 5 255 255 255 255 255 255 0 0 0 255 255 0 255 0 255 255 0 0 0 255 255 255 255 255 255 樣例輸出 1
首先搜索確定矩形框架,由題意得只有一個矩陣,所以按順序搜到的第一個等於0的點一定是矩陣的左上角的頂點,假設為(i,j)。以(i,j)為基礎,豎着在第j列搜,搜到一個點不是0或超出邊界,即確定了矩陣左下角的頂點(x,j)。橫着在第i行搜,搜到一個點不是0或超出邊界,即確定了矩陣右上角的頂點(i,y),右下角的頂點為(x,y)。所以這個矩陣一共包含像素點(x-i+1)*(y-j+1)個,邊緣有(x-i+y-j)*2個像素點,兩個做差就是內部的像素點個數

1 #include<iostream> 2 using namespace std; 3 int n,a[1001][1001]; 4 int main() 5 { 6 cin>>n; 7 for(int i=1;i<=n;i++) 8 for(int j=1;j<=n;j++) 9 cin>>a[i][j]; 10 for(int i=1;i<=n;i++) 11 for(int j=1;j<=n;j++) 12 if(!a[i][j]) 13 { 14 int x=i,y=j; 15 while(x<=n) 16 { 17 x++; 18 if(a[x][j]) break; 19 } 20 x--;//前面x先++,在判斷,所以break時x是已經超出邊界或不符合條件的,所以要減1 21 while(y<=n) 22 { 23 y++; 24 if(a[i][y]) break; 25 } 26 y--;//減1的原理同上 27 int tot=(x-i+1)*(y-j+1);//總共的像素點 28 int bian=(x-i+y-j)*2;//邊緣上的像素點 29 cout<<tot-bian; 30 return 0; 31 } 32 }
T19 腫瘤檢測
描述
一張CT掃描的灰度圖像可以用一個N*N(0 < N <= 100)的矩陣描述,矩陣上的每個點對應一個灰度值(整數),其取值范圍是0-255。我們假設給定的圖像中有且只有一個腫瘤。在圖上監測腫瘤的方法如下:如果某個點對應的灰度值小於等於50,則這個點在腫瘤上,否則不在腫瘤上。我們把在腫瘤上的點的數目加起來,就得到了腫瘤在圖上的面積。任何在腫瘤上的點,如果它是圖像的邊界或者它的上下左右四個相鄰點中至少有一個是非腫瘤上的點,則該點稱為腫瘤的邊界點。腫瘤的邊界點的個數稱為腫瘤的周長。現在給定一個圖像,要求計算其中的腫瘤的面積和周長。
輸入
輸入第一行包含一個正整數N(0 < N <= 100),表示圖像的大小;接下來N行,每行包含圖像的一行。圖像的一行用N個整數表示(所有整數大於等於0,小於等於255),兩個整數之間用一個空格隔開。
輸出
輸出只有一行,該行包含兩個正整數,分別為給定圖像中腫瘤的面積和周長,用一個空格分開。

樣例輸入 6 99 99 99 99 99 99 99 99 99 50 99 99 99 99 49 49 50 51 99 50 20 25 52 99 40 50 99 99 99 99 99 99 99 99 99 99 樣例輸出 9 8
方法1:BFS,但是這道題題目描述有點問題,實際測試數據中有多個腫瘤,BFS只按一個腫瘤算只能拿4分。
方法2:枚舉每一個元素,小於等於50則s+1,枚舉完了s即為腫瘤面積,對於每一個小於等於50的元素判斷是否是邊界,是則c+1,最后c為周長,此種方法可以忽略有幾個腫瘤的干擾,比BFS慢了2ms

#include<iostream> using namespace std; int n; int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; int a[101][101]; bool v[101][101]; int s,bian; void dfs(int x,int y) { s++; int ok=0; for(int i=0;i<4;i++) { int nx=x+dx[i],ny=y+dy[i]; if(nx>0&&nx<=n&&ny>0&&ny<=n&&a[nx][ny]<=50) { if(!v[nx][ny]) { v[nx][ny]=true; dfs(nx,ny); } } else ok=1; } if(ok) bian++; } int main() { cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(a[i][j]<=50&&!v[i][j]) { v[i][j]=true; dfs(i,j); } cout<<s<<' '<<bian; return 0; }

#include<iostream> using namespace std; int main() { int n,i,j,k,dx[]={1,-1,0,0},dy[]={0,0,1,-1},a[101][101],s=0,c=0; cin>>n; for(i=1;i<=n;i++) for(j=1;j<=n;j++) cin>>a[i][j]; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(a[i][j]<=50) { s++; for(k=0;k<4;k++) if(a[i+dx[k]][j+dy[k]]>50||i==1||i==n||j==1||j==n) { c++; break; } } cout<<s<<" "<<c; }
T20 反反復復
描述
Mo和Larry發明了一種信息加密方法。他們首先決定好列數,然后將信息(只包含字母)從上往下依次填入各列,並在末尾補充一些隨機字母使其成為一個完整的字母矩陣。例如,若信息是“There's no place like home on a snowy night”並且有5列,Mo會寫成:
t o i o y
h p k n n
e l e a i
r a h s g
e c o n h
s e m o t
n l e w x
注意Mo只會填入字母,且全部是小寫形式。在這個例子中,Mo用字母“x”填充了信息使之成為一個完整的矩陣,當然他使用任何字母都是可以的。
Mo根據這個矩陣重寫信息:首先從左到右寫下第一行,然后從右到左寫下第二行,再從左到右寫下第三行……以此左右交替地從上到下寫下各行字母,形成新的字符串。這樣,例子中的信息就被加密為:toioynnkpheleaigshareconhtomesnlewx。
你的工作是幫助Larry從加密后的信息中還原出原始信息(包括填充的字母)。
輸入
第一行包含一個整數(范圍2到20),表示使用的列數。
第二行是一個長度不超過200的字符串。
輸出
一行,即原始信息。

樣例輸入 5 toioynnkpheleaigshareconhtomesnlewx 樣例輸出 theresnoplacelikehomeonasnowynightx
將加密后的字符串橫着蛇形存儲到數組中,再豎着一列一列的輸出來

1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int n; 5 char a[201][21],b[201]; 6 int main() 7 { 8 cin>>n; 9 cin>>b; 10 int l=0,i=1,j=0; 11 int p=1; 12 while(l<strlen(b))//蛇形存儲 13 { 14 if(p==1) j++; 15 else if(p==2) j--; 16 if(j>n) 17 { 18 j=n;p=2;i++; 19 } 20 if(j<1) 21 { 22 j=1;p=1;i++; 23 } 24 a[i][j]=b[l]; 25 l++; 26 } 27 for(int m=1;m<=n;m++) 28 for(int k=1;k<=i;k++) 29 cout<<a[k][m]; 30 }