noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25
T21 二維數(shù)組右上左下遍歷
描述
給定一個(gè)row行col列的整數(shù)數(shù)組array,要求從array[0][0]元素開(kāi)始,按從左上到右下的對(duì)角線順序遍歷整個(gè)數(shù)組。
輸入
輸入的第一行上有兩個(gè)整數(shù),依次為row和col。
余下有row行,每行包含col個(gè)整數(shù),構(gòu)成一個(gè)二維整數(shù)數(shù)組。
(注:輸入的row和col保證0 < row < 100, 0 < col < 100)
輸出
按遍歷順序輸出每個(gè)整數(shù)。每個(gè)整數(shù)占一行。
樣例輸入 3 4 1 2 4 7 3 5 8 10 6 9 11 12 樣例輸出 1 2 3 4 5 6 7 8 9 10 11 12 樣例先枚舉第一行,向左下枚舉,再枚舉最后一列(除去右上角,因?yàn)榈谝恍幸呀?jīng)枚舉過(guò)了)
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 j=1;j<=m;j++)//枚舉第一行 11 { 12 int i=1,k=j;//i:當(dāng)前行,k:當(dāng)前列 13 while(i<=n&&k>0)//不超邊界 14 { 15 cout<<a[i][k]<<endl; 16 i++;k--; 17 } 18 } 19 for(int i=2;i<=n;i++)//最后一列,從第二行開(kāi)始 20 { 21 int j=m,k=i;//j:當(dāng)前列,k:當(dāng)前行 22 while(k<=n&&j>0)//不超邊界 23 { 24 cout<<a[k][j]<<endl; 25 k++;j--; 26 } 27 } 28 } View Code第一次枚舉最后一列時(shí)從第一行開(kāi)始的,0分。。。。。。
T22 神奇的幻方
描述
幻方是一個(gè)很神奇的N*N矩陣,它的每行、每列與對(duì)角線,加起來(lái)的數(shù)字和都是相同的。
我們可以通過(guò)以下方法構(gòu)建一個(gè)幻方。(階數(shù)為奇數(shù))
1.第一個(gè)數(shù)字寫(xiě)在第一行的中間
2.下一個(gè)數(shù)字,都寫(xiě)在上一個(gè)數(shù)字的右上方:
????a.如果該數(shù)字在第一行,則下一個(gè)數(shù)字寫(xiě)在最后一行,列數(shù)為該數(shù)字的右一列
????b.如果該數(shù)字在最后一列,則下一個(gè)數(shù)字寫(xiě)在第一列,行數(shù)為該數(shù)字的上一行
????c.如果該數(shù)字在右上角,或者該數(shù)字的右上方已有數(shù)字,則下一個(gè)數(shù)字寫(xiě)在該數(shù)字的下方
輸入
一個(gè)數(shù)字N(N<=20)
輸出
按上方法構(gòu)造的2N-1 * 2N-1的幻方
樣例輸入 3 樣例輸出 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9 樣例類似于NOIP2015 Day1 T1,但這道題是2*n-1階的
1 #include<iostream> 2 using namespace std; 3 int n,a[50][50]; 4 int main() 5 { 6 cin>>n; 7 a[1][n]=1; 8 int i=2,x=1,y=n; 9 while(i<=(2*n-1)*(2*n-1)) 10 { 11 if((x==1&&y==2*n-1)||a[x-1][y+1]) x+=1; 12 else if(x==1) x=2*n-1,y+=1; 13 else if(y==2*n-1) x-=1,y=1; 14 else x-=1,y+=1; 15 a[x][y]=i++; 16 } 17 for(int k=1;k<=2*n-1;k++) 18 { 19 for(int l=1;l<=2*n-1;l++) 20 cout<<a[k][l]<<' '; 21 cout<<endl; 22 } 23 } View CodeT23 二維數(shù)組回形遍歷
描述
給定一個(gè)row行col列的整數(shù)數(shù)組array,要求從array[0][0]元素開(kāi)始,按回形從外向內(nèi)順時(shí)針順序遍歷整個(gè)數(shù)組。如圖所示:
輸入
輸入的第一行上有兩個(gè)整數(shù),依次為row和col。
余下有row行,每行包含col個(gè)整數(shù),構(gòu)成一個(gè)二維整數(shù)數(shù)組。
(注:輸入的row和col保證0 < row < 100, 0 < col < 100)
輸出
按遍歷順序輸出每個(gè)整數(shù)。每個(gè)整數(shù)占一行。
樣例輸入 4 4 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 樣例輸出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 樣例遞歸遍歷即可,一定要注意一個(gè)格子只能走一遍以及判斷是否輸出了所有數(shù),不然會(huì)遞歸死循環(huán)
1 #include<iostream> 2 using namespace std; 3 int n,m,a[101][101]; 4 bool v[101][101]; 5 bool ok; 6 bool judge()//判斷是否已經(jīng)輸出了所有的數(shù) 7 { 8 for(int i=1;i<=n;i++) 9 for(int j=1;j<=m;j++) 10 if(!v[i][j]) return false; 11 return true; 12 } 13 //R向右 ,D向下,L向左,U向上 14 void dfs(int x,int y,char p)//x:當(dāng)前行,y:當(dāng)前列,p判斷向哪兒走 15 { 16 if(ok) return;//在judge之前先判斷是否已經(jīng)輸出了所有點(diǎn),防止輸出完遞歸回退時(shí)多次執(zhí)行judge函數(shù),浪費(fèi)時(shí)間 17 ok=judge(); 18 if(p=='R')//可以向右走 19 { 20 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])//不超邊界且沒(méi)有被遍歷 21 { 22 cout<<a[x][y]<<endl; 23 v[x][y]=true; 24 dfs(x,y+1,'R');//繼續(xù)向右走 25 } 26 else p='D',dfs(x+1,y-1,'D');//轉(zhuǎn)為向下走,當(dāng)執(zhí)行這個(gè)語(yǔ)句時(shí),y已經(jīng)超出了邊界,所以要減1,向下走x+1 27 } 28 else if(p=='D') 29 { 30 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 31 { 32 cout<<a[x][y]<<endl; 33 v[x][y]=true; 34 dfs(x+1,y,'D'); 35 } 36 else p='L',dfs(x-1,y-1,'L'); 37 } 38 else if(p=='L') 39 { 40 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 41 { 42 cout<<a[x][y]<<endl; 43 v[x][y]=true; 44 dfs(x,y-1,'L'); 45 } 46 else p='U',dfs(x-1,y+1,'U'); 47 } 48 else if(p=='U') 49 { 50 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 51 { 52 cout<<a[x][y]<<endl; 53 v[x][y]=true; 54 dfs(x-1,y,'U'); 55 } 56 else p='R',dfs(x+1,y+1,'R'); 57 } 58 } 59 int main() 60 { 61 cin>>n>>m; 62 for(int i=1;i<=n;i++) 63 for(int j=1;j<=m;j++) 64 cin>>a[i][j]; 65 dfs(1,1,'R'); 66 } View CodeT24 蛇形填充數(shù)組
描述
用數(shù)字1,2,3,4,...,n*n這n2個(gè)數(shù)蛇形填充規(guī)模為n*n的方陣。
蛇形填充方法為:
對(duì)于每一條左下-右上的斜線,從左上到右下依次編號(hào)1,2,...,2n-1;按編號(hào)從小到大的順序,將數(shù)字從小到大填入各條斜線,其中編號(hào)為奇數(shù)的從左下向右上填寫(xiě),編號(hào)為偶數(shù)的從右上到左下填寫(xiě)。
比如n=4時(shí),方陣填充為如下形式:
1??2??6??7 3??5??8??13 4??9??12 14 10 11 15 16輸入
輸入一個(gè)不大于10的正整數(shù)n,表示方陣的行數(shù)。
輸出
輸出該方陣,相鄰兩個(gè)元素之間用單個(gè)空格間隔。
注意處理邊界情況。
? ? ? ? ? ? ? ?
①:超出矩陣上邊界,此時(shí)位置坐標(biāo)已經(jīng)到①出,列與拐彎后的位置的列相等,行少了1,所以行+1,列不變
②:超出矩陣右邊界,此時(shí)位置坐標(biāo)已經(jīng)到②出,行與拐彎后的位置的行少了2行,列多了一列,所以行+2,列-1
③:即超出上邊界,又超出右邊界,此時(shí)位置到③處,我們可以手算一下,若先執(zhí)行①,再執(zhí)行②,會(huì)到達(dá)A處;先執(zhí)行②,再執(zhí)行①,會(huì)到達(dá)B處,而拐彎后的目標(biāo)位置為B處,所以在程序中,要先判斷②的情況,在判斷①的情況。
當(dāng)然為了避免③的情況,也可以另寫(xiě)一個(gè)語(yǔ)句直接判斷
如果不是邊界,直接行減1,列加1
當(dāng)向左下方填充時(shí),情況類似,就不再寫(xiě)了
1 #include<iostream> 2 using namespace std; 3 int n,a[11][11]; 4 bool ok; 5 int main() 6 { 7 cin>>n; 8 int s=0,p=1; 9 int x=1,y=1; 10 while(s<n*n)//填充,具體解釋看上面的題解 11 { 12 while(p%2==0&&s<n*n) 13 { 14 ok=false; 15 s++; 16 a[x][y]=s; 17 x++;y--; 18 if(x>n) x--,y+=2,ok=true; 19 if(y<1) y++,ok=true; 20 if(ok) p++; 21 } 22 while(p%2==1&&s<n*n) 23 { 24 ok=false; 25 s++; 26 a[x][y]=s; 27 x--;y++; 28 if(y>n) x+=2,y--,ok=true; 29 if(x<1) x++,ok=true; 30 if(ok) p++; 31 } 32 } 33 for(int i=1;i<=n;i++) 34 { 35 for(int j=1;j<=n;j++) 36 cout<<a[i][j]<<' '; 37 cout<<endl; 38 } 39 } View Code一開(kāi)始沒(méi)考慮③的情況,先判斷的①,在判斷的②,導(dǎo)致對(duì)角線拐彎時(shí)錯(cuò)行
T25 螺旋加密
描述
Chip和Dale發(fā)明了一種文本信息加密技術(shù)。他們事先秘密約定好矩陣的行數(shù)和列數(shù)。接著,將字符按如下方式編碼:
1. 所有文本只包含大寫(xiě)字母和空格。
2. 每個(gè)字符均賦予一個(gè)數(shù)值:空格=0,A=1,B=2,……,Y=25,Z=26。
按照下圖所示的方式,將每個(gè)字符對(duì)應(yīng)數(shù)值的5位二進(jìn)制數(shù)依次填入矩陣。最后用0將矩陣補(bǔ)充完整。例如,對(duì)于信息“ACM”,行列數(shù)均為4時(shí),矩陣將被填充為:
將矩陣中的數(shù)字按行連起來(lái)形成數(shù)字串,完成加密。例子中的信息最終會(huì)被加密為:0000110100101100。
輸入
一行。首先是兩個(gè)整數(shù)R(1≤R≤20)和C(1≤C≤20),表示行數(shù)和列數(shù)。之后是一個(gè)只包含大寫(xiě)字母和空格的字符串。字符串的長(zhǎng)度≤(R*C)/5。R和C之間以及C和字符串之間均用單個(gè)空格隔開(kāi)。
輸出
一行,為加密后的二進(jìn)制串。注意你可能需要用0將矩陣補(bǔ)充完整。
先將字符串按要求轉(zhuǎn)化為二進(jìn)制數(shù)字,然后再用類似T23二維數(shù)組回形遍歷的方法把數(shù)字存到矩陣?yán)?#xff0c;最后按順序輸出。這種方法雖然麻煩點(diǎn)兒,但比較快,用時(shí)0ms
注意數(shù)據(jù)的讀入方式,為了防止讀入多余的空格或少讀空格,可以將一整行當(dāng)字符串用gets讀進(jìn)去,再找空格分開(kāi)。也可以多輸入一個(gè)getchar()語(yǔ)句。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int n,m,a[101][101]; 6 char s[100]; 7 int ss[1000]; 8 bool v[101][101]; 9 int sum; 10 //R向右 ,D向下,L向左,U向上 11 void dfs(int x,int y,char p)//x:當(dāng)前行,y:當(dāng)前列,p判斷向哪兒走 12 { 13 if(sum==n*m) return; 14 if(p=='R')//可以向右走 15 { 16 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])//不超邊界且沒(méi)有被填充 17 { 18 a[x][y]=ss[++sum]; 19 v[x][y]=true; 20 dfs(x,y+1,'R');//繼續(xù)向右走 21 } 22 else p='D',dfs(x+1,y-1,'D');//轉(zhuǎn)為向下走,當(dāng)執(zhí)行這個(gè)語(yǔ)句時(shí),y已經(jīng)超出了邊界,所以要減1,向下走x+1 23 } 24 else if(p=='D') 25 { 26 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 27 { 28 a[x][y]=ss[++sum]; 29 v[x][y]=true; 30 dfs(x+1,y,'D'); 31 } 32 else p='L',dfs(x-1,y-1,'L'); 33 } 34 else if(p=='L') 35 { 36 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 37 { 38 a[x][y]=ss[++sum]; 39 v[x][y]=true; 40 dfs(x,y-1,'L'); 41 } 42 else p='U',dfs(x-1,y+1,'U'); 43 } 44 else if(p=='U') 45 { 46 if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y]) 47 { 48 a[x][y]=ss[++sum]; 49 v[x][y]=true; 50 dfs(x-1,y,'U'); 51 } 52 else p='R',dfs(x+1,y+1,'R'); 53 } 54 } 55 int main() 56 { 57 gets(s); 58 int i; 59 for(i=0;i<strlen(s);i++)//取出行 n 60 { 61 if(s[i]!=' ') n=n*10+s[i]-'0'; 62 else break; 63 } 64 int j; 65 for(j=i+1;j<strlen(s);j++)//取出列 m 66 { 67 if(s[j]!=' ') m=m*10+s[j]-'0'; 68 else break; 69 } 70 int l=0; 71 for(int k=j+1;k<strlen(s);k++) //將字符串轉(zhuǎn)化為二進(jìn)制 72 { 73 if(s[k]==' ')//空格的情況時(shí)5個(gè)0 74 for(int u=1;u<=5;u++) ss[++l]=0; 75 else 76 { 77 l+=5;//倒著填二進(jìn)制數(shù) 78 int p=s[k]-64,w=0; 79 while(p) 80 { 81 ss[l]=p%2; 82 p/=2; 83 l--; 84 } 85 while(l%5) ss[l]=0,l--;//二進(jìn)制位數(shù)有可能不足5位 86 l+=5;//前面倒著填的再加回去 87 } 88 } 89 for(int k=l+1;k<=n*m;k++) 90 ss[k]=0;//用0將矩陣補(bǔ)充完整 91 dfs(1,1,'R'); 92 for(int p=1;p<=n;p++) 93 for(int k=1;k<=m;k++) 94 cout<<a[p][k]; 95 } View Code下附簡(jiǎn)短代碼,用時(shí)1ms
精簡(jiǎn)之處1:cin、getchar()與getline()的使用省去上面用gets讀入在分離的過(guò)程
精簡(jiǎn)之處2:打表提前打出26個(gè)英文字符的二進(jìn)制,利用c++自帶的substr函數(shù)省去循環(huán)5次存儲(chǔ)五位二進(jìn)制的過(guò)程
精簡(jiǎn)之處3:將二進(jìn)制數(shù)存到矩陣中時(shí),以矩陣的一圈為單位,依次以(1,1)、(2,2)、(3,3)等為起點(diǎn),用while一圈一圈的存儲(chǔ),而不是dfs
精簡(jiǎn)之處4:題目要求,用0將矩陣補(bǔ)充完整,全局變量定義數(shù)組初始值即為0,可以不用管
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,l,c,x,y,t,a[105][105]; 4 string s,ss,q="0000100010000110010000101001100011101000010010101001011011000110101110011111000010001100101001110100101011011010111110001100111010"; 5 int main() 6 { 7 cin>>n>>m; 8 getchar(); 9 getline(cin,s); 10 l=s.size(); 11 for(int k=0;k<l;k++) 12 if(s[k]==' ') ss+="00000"; 13 else ss+=q.substr(5*(s[k]-'A'),5); 14 while(t<5*l) 15 { 16 c++;x=c;y=c; 17 while(y+c<=m+1&&t<5*l){a[x][y]=ss[++t-1]-'0';y++;}y--;x++; 18 while(x+c<=n+1&&t<5*l){a[x][y]=ss[++t-1]-'0';x++;}x--;y--; 19 while(y>=c&&t<5*l){a[x][y]=ss[++t-1]-'0';y--;}y++;x--; 20 while(x>c&&t<5*l){a[x][y]=ss[++t-1]-'0';x--;} 21 } 22 for(int i=1;i<=n;i++) 23 for(int j=1;j<=m;j++) 24 cout<<a[i][j]; 25 return 0; 26 } View Code2?
轉(zhuǎn)載于:https://www.cnblogs.com/TheRoadToTheGold/p/6106163.html
總結(jié)
以上是生活随笔為你收集整理的noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Docker下载Nginx镜像并运行Ng
- 下一篇: ORB-SLAM2图像预处理流程概括