2022-6-27
如何回形遍历一个矩阵:
1 #include2 #include 3 #include 4 #include <string.h> 5 int m,n; 6 int main() 7 { 8 scanf("%d%d",&m,&n); 9 int a[m][n],visit[m][n]; 10 memset(visit,0,sizeof(visit)); 11 for(int i=0;i ){ 12 for(int j=0;j ){ 13 scanf("%d",&a[i][j]); 14 } 15 } 16 int b[m*n]; 17 int cnt=0,i=0,j=0; 18 int *p=0; 19 b[0]=a[0][0],visit[0][0]=1; 20 while(cnt 1){ 21 while(j 1 && visit[i][j+1]==0)cnt++,p=*(a+i)+j+1,b[cnt]=*p,j++,visit[i][j]=1; 22 while(i 1 && visit[i+1][j]==0)cnt++,p=*(a+i+1)+j,b[cnt]=*p,i++,visit[i][j]=1; 23 while(j>0 && visit[i][j-1]==0)cnt++,p=*(a+i)+j-1,b[cnt]=*p,j--,visit[i][j]=1; 24 while(i>0 && visit[i-1][j]==0)cnt++,p=*(a+i-1)+j,b[cnt]=*p,i--,visit[i][j]=1; 25 } 26 for(int i=0;i ){ 27 printf("%d ",b[i]); 28 } 29 return 0; 30 }
矩阵乘法:(三重循环,我这个脑子太好使了)
1 #include2 #include 3 #include 4 #define MOD 10000007//为防止溢出,取模 5 int a[7][7],b[7][7],c[7][7],x,y,z;//x,y是数组a的行数和列数,数组b的列数和行数 6 void createRandomArray(){ 7 x=rand()%5,y=rand()%5,z=rand()%5; 8 for(int i=0;i ){ 9 for(int j=0;j ){ 10 a[i][j]=rand()%100;//矩阵中所有元素均在0-100之间 11 } 12 } 13 for(int i=0;i ){ 14 for(int j=0;j ){ 15 b[i][j]=rand()%100; 16 } 17 } 18 } 19 void calArrayMultiply(){ 20 for(int i=0;i ) 21 for(int j=0;j ) 22 for(int k=0;k ) 23 c[i][j]+=a[i][k]*b[k][j]%MOD;//用三重循环实现乘法 24 } 25 int main() 26 { 27 srand((unsigned)time(NULL)); 28 createRandomArray(); 29 calArrayMultiply(); 30 puts("以下是第一个矩阵:"); 31 for(int i=0;i ){ 32 for(int j=0;j ){ 33 printf("%3d",a[i][j]); 34 } 35 puts(""); 36 } 37 puts("以下是第二个矩阵:"); 38 for(int i=0;i ){ 39 for(int j=0;j ){ 40 printf("%3d",b[i][j]); 41 } 42 puts(""); 43 } 44 puts("以下是结果矩阵:"); 45 for(int i=0;i ){ 46 for(int j=0;j ){ 47 printf("%-8d",c[i][j]); 48 } 49 puts(""); 50 } 51 return 0; 52 }
插入(双指针):
1 //第五题 2 #include3 #include 4 #include 5 int main() 6 { 7 int a[11]; 8 for(int i=0;i<10;i++)a[i]=rand()%20; 9 for(int i=0;i<10;i++){ 10 int minindex=i; 11 for(int j=i;j<10;j++){ 12 if(a[j]<a[minindex]){ 13 minindex=j; 14 } 15 } 16 if(i!=minindex){ 17 int t=a[i]; 18 a[i]=a[minindex]; 19 a[minindex]=t; 20 } 21 } 22 printf("插入前:\n"); 23 for(int i=0;i<10;i++){ 24 printf("%d ",a[i]); 25 if(i==6)printf("\n"); 26 } 27 printf("\n"); 28 int x; 29 scanf("%d",&x); 30 int i; 31 for(i=0;i<10;i++){ 32 if(x>=a[i]){ 33 if(i==9){ 34 printf("在这:%d\n",i); 35 break; 36 } 37 else{ 38 if(x<=a[i+1])break; 39 } 40 } 41 } 42 int p1,p2=x; 43 for(int j=i+1;j<11;j++){ 44 p1=a[j]; 45 a[j]=p2; 46 p2=p1; 47 } 48 printf("\n插入后:\n"); 49 for(int j=0;j<11;j++){ 50 printf("%d ",a[j]); 51 if(j==6)printf("\n"); 52 } 53 return 0; 54 }
矩阵旋转:(用好下标变换)
1 #include2 #include 3 #include <string.h> 4 #include 5 void zhuan(int n,int angle,int a[][5],int b[][5]){ 6 if(angle==90){ 7 for(int i=0;i ){ 8 for(int j=0;j ){ 9 b[i][j]=a[j][n-i-1]; 10 } 11 } 12 } 13 else if(angle==180){ 14 for(int i=0;i ){ 15 for(int j=0;j ){ 16 b[i][j]=a[n-i-1][n-1-j]; 17 } 18 } 19 } 20 else{ 21 for(int i=0;i ){ 22 for(int j=0;j ){ 23 b[i][j]=a[n-j-1][i]; 24 } 25 } 26 } 27 } 28 int main() 29 { 30 //int x; 31 //puts("请输入想要的阶数:"); 32 //scanf("%d",&x); 33 //x=5; 34 int a[5][5],b[5][5]; 35 puts("这是没有旋转的矩阵:"); 36 for(int i=0;i<5;i++){ 37 for(int j =0;j<5;j++){ 38 a[i][j]=rand()%20; 39 printf("%-3d",a[i][j]); 40 } 41 puts(""); 42 } 43 puts("请输入要旋转的角度:"); 44 int angle; 45 scanf("%d",&angle); 46 puts(""); 47 zhuan(5,angle,a,b); 48 puts("这是旋转以后的矩阵:"); 49 for(int i=0;i<5;i++){ 50 for(int j =0;j<5;j++){ 51 printf("%-3d",b[i][j]); 52 } 53 puts(""); 54 } 55 return 0; 56 }
多源最短路(在曼哈顿图中)(无例题)(使用BFA,队列):
操作的地图要有两个特点:既可以表示结果中所要的最短距离,又能记录这个点是否走过,那就全部memset为一个特殊的数-1(这里一定要专门设计一个结果图,不能只用最初的图,让最初的图承担三个责任,它哪里做的到啊(表示举例,判重,记录最初信息)(非要做的话,你可以想象,如果发现一个点可以是起点,那就改变其值为0,这个0要如何与其他没去过的点的0区分呢,如果另开一个数组那就可以区分了,起点处是0,没去过的地方是-1)),这就是个特殊的判重技巧:另开一个数组。
本题代码有个bug,不知道为什么输出结果有误,以后改过来。
题目:
code:
1 #include2 using namespace std; 3 int n,m,a[100][100],b[100][100]; 4 struct node{int x,y;}; 5 int hx[]={0,0,1,-1}; 6 int hy[]={1,-1,0,0}; 7 queue q; 8 void bfs(){ 9 while(q.size()){ 10 node t=q.front(); 11 q.pop(); 12 for(int i=0;i<4;i++){ 13 int dx=t.x+hx[i],dy=t.y+hy[i]; 14 if(dx>=0&&dx =0&&dy 1){ 15 b[dx][dy]=b[t.x][t.y]+1,q.push({dx,dy}); 16 } 17 } 18 } 19 } 20 int main(){ 21 cin>>n>>m; 22 memset(b,-1,sizeof(b)); 23 for(int i=0;i ){ 24 for(int j=0;j ){ 25 cin>>a[i][j]; 26 if(a[i][j]==1)q.push({i,j}),b[i][j]=0; 27 } 28 } 29 bfs(); 30 for(int i=0;i ){ 31 for(int j=0;j ){ 32 cout<" "; 33 } 34 cout<<endl; 35 } 36 return 0; 37 }
一道很有趣的条件纠缠问题:
某侦察队接到一项紧急任务,要求在A、B、C、D、E、F六个队员中尽可能多地挑若干人,但有以下限制条件:
1)A和B两人中至少去一人;
2)A和D不能一起去;
3)A、E和F三人中要派两人去;
4)B和C都去或都不去;
5)C和D两人中去一个;
6)若D不去,则E也不去。
试编写一个程序,输出问应当让哪几个人去?
解法:用深搜遍历每一种可能性。将约束条件写成函数即可求出所有合理的解法,在解法中找到去的人数最多的那一种即可。
code:(本题是C语言程序设计实践的上机题,所以使用C语言写成)(注意约束条件是怎么写的,不要把”ABC有两个人去“写成“ABC都去不行”||“ABC都不去不行”||“A去了BC没去”……这种形式,这一看头都快破掉了,然而我最初就真是这么写的……我这个脑子呦)
再注意一点:DFS是有模板的,虽说不要求背诵模板,但起码要有个大致的印象,比如本题中前6层的递归都是在找答案,到了第七层就输出答案,所以出口的条件就是if(n==6)
对了,if的出口之后记得加一个else,这是必备的,否则就会数组越界。
1 #include2 #include <string.h> 3 int a[6];//0表示没去,1表示去了 4 int right(){ 5 if(a[0]==0&&a[1]==0)return 0; 6 7 if(a[0]&&a[3])return 0; 8 9 int cnt=0; 10 if(a[0])cnt++; 11 if(a[4])cnt++; 12 if(a[5])cnt++; 13 if(cnt!=2)return 0; 14 15 if((a[1]==0&&a[2])||(a[1]&&a[2]==0))return 0; 16 17 int cnt1=0; 18 if(a[2])cnt1++; 19 if(a[3])cnt1++; 20 if(cnt1!=1)return 0; 21 22 if(!a[3]&&a[4])return 0; 23 24 return 1; 25 } 26 void dfs(int p){ 27 if(p==6){ 28 if(right()){ 29 for(int i=0;i<6;i++)if(a[i])printf("%c去了 ",i+'A'); 30 printf("\n"); 31 } 32 } 33 else 34 for(int i=0;i<2;i++){ 35 a[p]=i; 36 dfs(p+1); 37 } 38 } 39 int main(int argc, char** argv) { 40 dfs(0); 41 return 0; 42 }
大致模板如下:
1 void dfs(){ 2 if(到达出口){ 3 出去吧你 4 }else{ 5 开探照灯 6 for(){ 7 if(判越界,判重){ 8 更新 9 dfs(下一层) 10 变回来 11 } 12 } 13 } 14 }
一道数学题:
我们知道,在10 进制数中有判断整除性的二个简单规则:一个正整数能够被3整除,当且仅当,它的各位数字之和能够被3整除;一个正整数能够被11整除,当且仅当,它的奇数位数字之和与偶数位数字之和的差能够被11整除;现在要问:对于b进制数,具有类似于10进制数的3和11的这种整除性判断的数是什么?具体地,请编写程序,输入进制的基数b,输出最小的可以如上判断整除性的数x和数y,输入输出均采用10 进制数.
示例 :
输入b为10,则自然要输出x为3,y为11; 若输入b为8,则要输出x为7, y为3 (例如8进制数25,按上述规则判断应能够被7和3整除,事实上,8进制数25是10进制数21,能够被7和3整除是显然的) ;若输入b为120,则要输出x为7, y为11 (请自己验证这是对的).
提示:对于10进制数,10-1=9=3*3, 10+1=11, 10进制数n可以一般地表示为:
n=ak10k+ak-110k-1+ ....+a110+a0
保持n不改变数值将10换为10-1和10+1,可以看出3和11可以如上判断整除性的理由.
思考:如果(b+1)%x==0,这个x就是你要找的;如果(b-1)%y==0,这个y就是你要找的。
code:
1 #include2 #include <string.h> 3 int main(int argc, char** argv) { 4 int b,x=2,y=2; 5 scanf("%d",&b); 6 while(1){ 7 if((b-1)%x == 0)break; 8 x++; 9 } 10 while(1){ 11 if((b+1)%y == 0)break; 12 y++; 13 } 14 printf("x=%d y=%d",x,y); 15 return 0; 16 }