Tải bản đầy đủ (.docx) (11 trang)

Các bài toán ma trận trong kĩ thuật lập trình

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (67.63 KB, 11 trang )

CÁC BÀI TOÁN TRÊN MA TRẬN
(Gồm có: Tạo ra ma trận xoắn ốc, Sudoku, Caro, Dò mìn ,Stack ,Queue ,Các thao tác cơ bản)
1. Tạo ra ma trận xoắn ốc :
void xoanoc(int a[][MAX], int n)
{
int k=1; //giá trị dùng để điền vào ma trận
int left=0, //các biên trái phải trên dưới
right=n-1, //dùng để làm chốt chặn
top=0,
bottom=n-1;
int i=0,j=-1; //tăng j trước rồi mới điền giá trị
while (k<=n*n){ //chưa điền đủ n*n số thì còn lặp
//B1: chạy dọc biên trên từ trái sang phải
while (j<right) a[i][++j] = k++;
top++; //điều chỉnh lại biên trên
//B2: chạy dọc biên phải từ trên xuống dưới
while (i<bottom) a[++i][j] = k++;
right ; //điều chỉnh lại biên phải
//B3: chạy dọc biên dưới từ phải sang trái
while (j>left) a[i][ j] = k++;
bottom ;
//B4: chạy dọc biên trái từ dưới lên trên
while (i>top) a[ i][j] = k++;
left++;
}
}
2. Caro :
void main()
{
int a[MAX][MAX],n;
docData(a,n);


inMat(a,n);
if(!kiemTraHopLe(a,n))
cout<<"Du lieu vao khong hop le !!!"<<endl;
else
{
cout<<"Du lieu vao hop le !!!"<<endl;
int kt=KiemTraThangThua(a,n);
if(kt!=-2)
cout<<kt<<" thang !!!"<<endl;
else
cout<<"Dang choi !!!"<<endl;
}
}
void docData(int a[MAX][MAX],int &n)
{
FILE *fin;
fopen_s(&fin,"INPUT.TXT","rt");
if(!fin)
{
cout<<"No file !!!"<<endl;
return;
}
// nhap n
fscanf_s(fin,"%d",&n);
// nhapma tran
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
fscanf_s(fin,"%d",&a[i][j]);
fclose(fin);
}

// in ma tran
void inMat(int a[MAX][MAX],int n)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
//cout<<a[i][j]<<"\t";
printf("%2d ",a[i][j]);
cout<<endl;
}
}
// kiem tra hop le
int kiemTraHopLe(int a[MAX][MAX],int n)
{
int demA=0,demB=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(a[i][j]==0 || a[i][j]==-1 || a[i][j]== 1)
{
if(a[i][j]==0)//dem cho ben A
demA++;
if(a[i][j]==1)// dem cho ben B
demB++;
}
else
{
return 0;
}
}

if(demA==demB || demA-demB==1 || demB-demA==1)
return 1;
return 0;
}
//
//kiem tra thang thua
int KiemTraThangThua(int a[MAX][MAX],int n)
{
if(n<5)
return -2;
else
{
//cac bien chung
int hs,// he so cong cua cac hang va cot
dem=0,// so lan bang nhau cua cac nuoc
i,j;// cac he so chay
//hang ngang
for(i=0;i<n;i++)//cac hang dang xet
{
for(hs=0;hs<=n-5;hs++)
{
for(j=hs;j<hs+4;j++)// xet 5 o hang ngang
{ // tu hs den hs+5
if(a[i][j]!=-1 && a[i][j+1]!=-1)
if(a[i][j]==a[i][j+1])
dem++;
else//ko bang nhau
j=hs+5;
else// co phan tu trong
j=hs+5;

}
if(dem==4)
{
cout<<"Thang hang ngang !!!"<<endl;
return a[i][hs];
}
dem=0;
}
}
//hang doc
dem=0;
for(j=0;j<n;j++)
{
for(hs=0;hs<=n-5;hs++)
{
for(i=hs;i<hs+4;i++)
{
if(a[i][j]!=-1 && a[i+1][j]!=-1)
if(a[i][j]==a[i+1][j])
dem++;
else//ko bang nhau
i=hs+5;
else//co phan tu trong
i=hs+5;
}
if(dem==4)
{
cout<<"Thang hang doc !!!"<<endl;
return a[hs][j];
}

dem=0;
}
}
//hang cheo
dem=0;
int demp=0;
for(i=0;i<=n-5;i++)// xet hang tu 0 den =n-5
for(j=0;j<=n-5;j++)//xet cot tu 0 den =n-5
{
for(int k=0;k<=3;k++)// he so cong 0 1 2 3
{
if(a[i+k][j+k]!=-1 && a[i+k+1][j+k+1]!=-1)
{
if(a[i+k][j+k]==a[i+k+1][j+k+1])//phan tu lien
tiep tren
dem++;
//hang cheo bang nhau
}
if( a[i+k][j+4-k]!=-1 && a[i+k+1][j+4-k-1]!=-1)
{
if( a[i+k][j+4-k]==a[i+k+1][j+4-k-1])
demp++;//phan tu tren hang cheo nguoc
}
}
if(dem==4)
{
cout<<"Thang hang cheo !!!"<<endl;
return a[i][j];
}
dem=0;

if(demp==4)
{
cout<<"Thang hang cheo !!!"<<endl;
return a[i][j+4];
}
demp=0;
}
}
return -2;
}
3. Dò mìn :
//ham random
int random(int n)
{
int a=rand();
return a%n;
}
//
//ham dat min vao ma tran
void datMin(int a[MAX][MAX],int n,int somin)
{
int i,j;
//khoi tao toan mang bang 0
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j]=0;
// dat tung qua vao ma tran
while(somin>0)
{
i=random(n);

j=random(n);
if(a[i][j]==0)// chua co min
{
a[i][j]=-1;// dat min vao
somin ; // cap nhat lai so min con lai
}
}
}
// tinh toan gia tri so min dat xung quanh
void tinhSoMin(int a[MAX][MAX],int n )
{
int i,j,k,l,dem;
//
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(a[i][j]!=-1)
{
dem=0;
for( k=i-1;k<=i+1;k++)
for( l=j-1;l<=j+1;l++)
if( k>=0 && k<n &&
l>=0 && l<n &&
(k!=i || l!=j) &&
a[k][l]==-1
)
{
dem++;
}
a[i][j]=dem;
}

}
// 6.viet ham tim vi tri ma xung quanh co nhieu min nhat
void ViTriNhieuMin(int a[MAX][MAX],int n)
{
int vti=0,vtj=0,
soMin,CoKhoiTao=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(a[i][j]!=-1)
{
if(CoKhoiTao==0)
{
soMin=a[i][j];
vti=i;
vtj=j;
CoKhoiTao=1;
}
else
{
if(a[i][j]>soMin)
{
soMin=a[i][j];
vti=i;
vtj=j;
}
}
}
}
printf("Vi tri nhieu min nhat la :[%d][%d]\n",vti,vtj);

}
//
// 7.tim vung co kich thuoc k*k (0<k<n)co it min nhat
//k cho truoc
void VungItMin(int a[MAX][MAX],int n,int k)
{
int CoKhoiTao=0,//co khoi tao
min=-1,//cho it min
vtmini=-1,vtminj=-1;//vi tri vung KxK
for(int i=0;i<n-k;i++)
for(int j=0;j<n-k;j++)
{
int tam=DemMin(a,n,i,j,k);
if(CoKhoiTao==0)
{
min=tam;
vtmini=i;
vtminj=j;
CoKhoiTao = 1;
}
else
{
if(tam<min)
{
min=tam;
vtmini=i;
vtminj=j;
}
}
}

cout<<"Vi tri vung k*k it min:["<<vtmini<<"]["<<vtminj<<"]"<<endl;
cout << "So min it nhat do la :" << min << endl;
}
//
//dem min trong pham vi KxK
int DemMin(int a[MAX][MAX],int n,int k,int vti,int vtj)
{
int dem=0;
for(int i=vti;i<vti+k;i++)
for(int j=vtj;j<vtj+k;j++)
{
if(a[i][j]==-1)
dem++;
}
return dem;
}
//
// 8.Ham cho biet vung lon nhat chua cac so 0 lien ke // co bao nhieu o
void DemO(int a[MAX][MAX],int n)
{
int Max=-1,//so o trong it nhat cua vung dang xet
CoMin=0,// co danh dau khoi tao Min
Vungi=-1,Vungj=-1;//vi tri vung it min nhat
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(a[i][j]==0)
{
int tami=i,tamj=j;//luu lai vi tri hien tai
a[i][j]=-9;

int dem=1,
kiemtra;
//luu vao stack
ST[top].i=i;
ST[top++].j=j;
//
DuyetO(a,n,i,j,kiemtra);
int isave=i,jsave=j;
//
while(top>0)//chua het stack
{
if(kiemtra==0)//het o duyet
{
i=ST[top-1].i;
j=ST[top-1].j;
top ;
}
else//con o chua duyet
{
a[i][j]=-9;
ST[top].i=isave;
ST[top].j=jsave;
top++;
dem++;
}
//printfMat(a,n);
//int chay;
//cin>>chay;
isave=i;//luu vi tri i dang duyet
jsave=j;//luu vi tri j dang duyet

DuyetO(a,n,i,j,kiemtra);
}
//khoi phuc lai i,j
i=tami;
j=tamj;
if(CoMin==0)// chua khoi tao max
{
Max=dem;
Vungi=i;
Vungj=j;
CoMin=1;
}
else
{
if(dem>Max)
{
Max=dem;
Vungi=i;
Vungj=j;
}
}
}
}
if(Max!=-1)
{
cout<<"Vung co nhieu o so 0 nhat la vung:[";
cout<<Vungi<<"]["<<Vungj<<"]"<<endl;
cout<<"So o vung do la:"<<Max<<endl;
}else
cout<<"khong co vung co o so 0 !!!"<<endl;

}
//
//ham kiem tra xem xung quanh con o nao duyet dc nua hay ko
//duyet tiep dc ->1
//ko duyet teip dc->0
void DuyetO(int a[MAX][MAX],int n,int &vti,int &vtj,int &kiemtra)
{
for(int i=vti-1;i<=vti+1; i++)
for(int j=vtj-1;j<=vtj+1;j++)
{
if(i>=0 && j>=0)
{
if(a[i][j]==0)
{
vti=i;
vtj=j;
//cout<<"Trong ij="<<vti<<" "<<vtj<<endl;
kiemtra=1;//con o de duyet tiep
return;
}
}
}
kiemtra=0;// het o de duyet
//khi ket thuc tra ra vi tri dau tien
//ma co the duyet den vao vti va vtj
}
4. Stack :
//Khai báo cấu trúc dữ liệu ngăn xếp (STACK)
//sử dụng mảng 1 chiều để lưu trữ nội dung
#define MAX 100

typedef struct {
int top;
int arr[MAX];
}STACK;
//Các thao tác trên ngăn xếp
//1. Khởi tạo 1 ngăn xếp rỗng
void init(STACK &s){
s.top = -1;
}
//2. Kiểm tra xem ngăn xếp có rỗng hay không
int isempty(STACK s){
return (s.top==-1);
}
//3. Kiểm tra xem ngăn xếp đã đầy hay chưa
int isfull(STACK s){
return (s.top==MAX-1);
}
//4. Cất 1 giá trị x vào ngăn xếp
void push(STACK &s, int value){
if (!isfull(s)){
s.top++;
s.arr[s.top] = value;
}
}
//5. Lấy 1 giá trị ra khỏi đỉnh ngăn xếp
int pop(STACK &s){
if (isempty(s)) return 0; //giá trị đặc biệt
int t = s.arr[s.top];
s.top ;
return t;

}
5. Các thao tác cơ bản :
//1. Tìm dòng có tổng lớn nhất của ma trận
//Trả về số thứ tự của dòng có tổng đạt max
//Tham số t chứa giá trị tổng của dòng đạt max
int maxdong(int a[][MAX], int d, int c, int &t)
{
int i,j,td=0,vt;
for(j=0; j<c; j++) td += a[0][j]; //tính tổng dòng 0
t = td; vt = 0; //giả sử dòng đầu đạt max
for(i=1; i<d; i++){ //duyệt từ dòng thứ 1 trở đi
td = 0; //tính lại từ đầu khi sang dòng mới
for(j=0; j<c; j++) td += a[i][j]; //tính tổng dòng i
if (t<td) { //dòng i có tổng lớn hơn
t = td; //cập nhật lại max
vt = i; //và chỉ số dòng
}
}
return vt;
}
//2. Cộng 2 ma trận (cùng kích thước dxc)
void congmt(int a[][MAX], int b[][MAX], int t[][MAX], int d, int c)
{
int i,j;
for(i=0; i<d; i++)
for(j=0; j<c; j++)
t[i][j] = a[i][j] + b[i][j];
}
//3. Nhân 2 ma trận (mxn) và (nxp)
//Ma trận tích có kích thước mxp

void nhanmt(int a[][MAX],int b[][MAX],int t[][MAX],int m, int n, int p)
{
int i,j,k;
for(i=0; i<m; i++) //duyệt qua ma trận T
for(j=0; j<p; j++){
t[i][j]=0; //khởi gán ban đầu
for(k=0; k<n; k++) //cộng dồn các tích
t[i][j] += a[i][k]*b[k][j];
}
}
//Một số thao tác trên ma trận vuông cấp nxn
//4. Kiểm tra ma trận đơn vị
int mtdonvi(int a[][MAX], int n)
{
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
if ((i==j && a[i][j]!=1)||(i!=j && a[i][j]!=0))
return 0;
return 1;
}
//5. Kiểm tra ma trận tam giác dưới
int mttamgiacduoi(int a[][MAX], int n)
{
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
if ((i>=j && a[i][j]==0)||(i<j && a[i][j]!=0))
return 0;
return 1;

}
//6. Kiểm tra ma trận tam giác trên
int mttamgiactren(int a[][MAX], int n)
{
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
if ((i<=j && a[i][j]==0)||(i>j && a[i][j]!=0))
return 0;
return 1;
}
//7. Kiểm tra ma trận đối xứng
int mtdoixung(int a[][MAX], int n)
{
int i,j;
for(i=0; i<n; i++)
for(j=i+1; j<n; j++)
if (a[i][j]!=a[j][i])
return 0;
return 1;
}
//8. Tạo ma trận chuyển vị
void mtchuyenvi(int a[][MAX], int at[][MAX], int n)
{
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
at[j][i] = a[i][j];
}
6. Hình vuông Latin:

//kiem tra cot
int ktcot(int a[MAX][MAX], int k,int n)
{
for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++)
{
if (a[i][k] && a[i][k]==a[j][k])
return 1;
if(a[i][j]>n || a[i][j]<1 )
return 1;
}
return 0;
}
//Kiểm tra dòng k có vi phạm hay không
int ktdong(int a[][MAX], int k,int n)
{
for(int i=0; i<n; i++)
for(int j=i+1; j<n; j++)
{
if (a[k][i] && a[k][i]==a[k][j])
return 1;
if(a[i][j]>n || a[i][j]<1 )
return 1;
}
return 0;
}
//kiểm tra vị trí i,j có vi phạm hay không
int VitriViPham(int a[MAX][MAX],int n,int i,int j)
{
int k;

k=ktdong(a,i,n);
if(k==1)
return 1;
k=ktcot(a,j,n);
if(k==1)
return 1;
return 0;
}

×