Tải bản đầy đủ (.doc) (23 trang)

Bài giải kỹ thuật lập trình ôn thi cao học Học viện công nghệ bưu chính viễn thông

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 (167.08 KB, 23 trang )

THUẬT TOÁN TÌM CẠNH CẦU DUYỆT THEO DFS
1. Khai báo biến:
- Mảng chứa ma trận a[max][max].
- Mảng chuaxet[max]= (true-1: chưa xét, false=0: đã xét)
- Biến int dinhke
- Typedef Struct { int u,v;} canh; canh canhcau[max]
2. Các hàm cần viết:
- Hàm input : đọc dữ liệu đầu vào.
- Hàm init_chuaxet: Ban đầu các đỉnh đều gán chuaxet=true;
- Hàm Duyet_DFS(int u)
{ chuaxet[u]=false; //danh dau u tham roi
for (int v=1;v<=n;v++)//xet cac dinh v tu 1 den n
if (chuaxet[v]==true&&a[u][v]==1)//neu v chua tham va v ke u
Duyet_DFS(v);//goi de qui de tham v
//tra ve ket qua nhung dinh ke voi dinh duoc xem la tru co nam trong danh sach
duong di khong
if (chuaxet[dinhke]==true) //neu van con dinh chua di qua
return false; //tra ve ket qua khong co duong di toi het cac dinh
return true;
}
- Hàm tim_canh_cau()
{ m=0;
for(t=1;t<=n;t++) //duyet dinh t tu 1 den n
for (j=t+1;j<=n;j++)
{ init_chuaxet(); //khoi tao mang chua xet, tat ca cac dinh la chua di
if (a[t][j]==1) //neu j la dinh ke voi t
{
a[t][j]=0; //loai bo canh noi giua 2 dinh
a[j][t]=0;
dinhke=j; //luu vao bien dinh ke
if (Duyet_DFS(t)==false) // neu duyet khong toi het cac dinh


{ canhcau[++m].u=t; //luu 2 dinh tao nen canh cau
canhcau[m].v=dinhke;
}
a[t][j] = 1; //tra lai canh vua bo
a[j][t] = 1;
}
}
}
- Hàm output: fprintf(fp,"(%d,%d) ",canhcau[i].u,canhcau[i].v);
- Hàm main: int main()
{input(); tim_canh_cau(); output();}

THUẬT TOÁN TÌM ĐỈNH TRỤ DUYỆT THEO BFS
1. Khai báo biến:
1


-

Mảng chứa ma trận a[max][max].
Mảng chuaxet[max]= (true-1: chưa xét, false=0: đã xét)
Mảng dinhke[max], dinhtru[max] : chứa các đỉnh kề và đỉnh trụ
Queue[max]: queue chứa các đỉnh kề
Int sodinh: số đỉnh kề của t

2. Các hàm cần viết:
- Hàm input : đọc dữ liệu đầu vào.
- Hàm init_chuaxet: Ban đầu các đỉnh đều gán chuaxet=true;
- Hàm Duyet_BFS(int t)
{ int dau,cuoi;//bien dau va bien cuoi de quan ly hang doi

dau=cuoi=1;//ban dau hang doi rong
queue[cuoi++]=t; //Dua dinh t vao queue
chuaxet[t]=false;//t da xet roi
while (dau!=cuoi)//Trong khi hang doi con khac rong
{ u=queue[dau++];//lan luot lay cac dinh trong queue ra, dinh u
for (v=1;v<=n;v++) //lan luot xet cac dinh v
if(a[u][v]==true&&chuaxet[v]==true) //neu v ke voi u va chua xet
{
chuaxet[v]=false;// v da xet roi
queue[cuoi++]=v;//dua v vao queue de xet tiep cac dinh ke voi v
}
}
//tra ve ket qua nhung dinh ke voi dinh duoc xem la tru co nam trong danh sach
duong di khong
for(i=1;i<=sodinh;i++)//so dinh ke cua t
if (chuaxet[dinhke[i]]==true) //neu van con dinh chua di qua
return false; //tre ve ket qua khong co duong di toi het cac dinh
return true;
}

-

Hàm tim_dinh_tru()
{
int p; m=0;
for(t=1;t<=n;t++) //duyet dinh t tu 1 den n
{ init_chuaxet(); //tat ca cac dinh la chua di
sodinh=0; //so dinh ke cua t la 0
for (i=1;i<=n;i++)
if (a[t][i]==1) //voi moi dinh ke voi t

{ p=i; //chon lay dinh de duyet kiem tra duong di
dinhke[++sodinh]=i;//luu lai danh sach dinh ke voi t
a[t][i]=0; //loai bo canh noi giua i va t
2


a[i][t]=0;
}
if (Duyet_BFS(p)==false) //neu dinh ke voi t di toi het cac dinh con lai
dinhtru[++m]=t; //thi t la dinh tru, luu vao mang dinh tru
//phuc hoi lai canh vua bo truoc do
for (i=1;i<=sodinh;i++)//i chay tu 1 den so dinh ke voi t
{
a[t][dinhke[i]]=1;
a[dinhke[i]][t]=1;
}
}
-

}
Hàm output: fprintf(fp,"%3d",dinhtru[i]);
Hàm main: int main()
{input(); tim_dinh_tru(); output();}

THUẬT TOÁN TÌM CT VÀ ĐĐ HAMILTON TỪ MA TRẬN KỀ

1. Khai báo biến:
-

Mảng chứa ma trận a[max][max].


-

Mảng tham[max]= (1: thăm rồi; 0: chưa thăm)

-

Mảng x[max] : lưu các đỉnh theo thứ tự của chu trình Hamilton

2. Các hàm cần viết:
-

Hàm DocFile : đọc dữ liệu đầu vào (ma trận kề)

-

Hàm Duyet (int i) : tìm đỉnh tiếp theo trong chu trình Hamilton
3


{ for(int j=1;j<=n;j++){//xet cac dinh j tu 1 den n
if(tham[j]==0&&a[x[i-1]][j]==1){//neu j chua tham va j ke voi x[i-1]
x[i]=j;//chon j lam dinh thu i trên chu trình
tham[j]=1;//danh dau dinh j tham roi
if (i==n){//neu da tim du n dinh
if(a[x[n]][x[1]]==1){//neu dinh thu n ke voi dinh thu 1
printf("\n%d)CT:",++count);
for(int
k=1;k<=n;k++){//in
chu

trình:
x[1],...,x[n],x[1]
printf("%d ",x[k]);
}
printf("%d",x[1]);
}else{//neu dinh thu n khong ke voi dinh thu 1
printf("\n%d)DD:",++count);
for(int k=1;k<=n;k++){//in duong di: x[1],...,x[n]
printf("%d ",x[k]);
}
}
}else{
Duyet(i+1) ;//goi de qui de tim dinh thu i+1
}
tham[j]=0 ;//bo tham dinh j
}
}
}

-

Hàm void Hamilton(int dxp){

for(int i=1;i<=n;i++) tham[i]=0;//ban dau tat ca cac dinh la chua tham
x[1]=dxp;//dxp la dinh thu nhat
tham[dxp]=1;//danh dau dxp tham roi
Duyet(2);//tim dinh thu 2
}
- Hàm int main() {
int dxp;

DocFile();
printf("nhap dxp:");scanf("%d",&dxp);
Hamilton(dxp);
4


getch();
}

THUẬT TOÁN TÌM CT VÀ ĐĐ HAMILTON TỪ DS CẠNH
-

Hàm DocFile(): Đọc danh sách cạnh và chuyển thành ma trận kề
{
int i,j ;
FILE *f= fopen("c:/dscanh.in","r");//mo file dscanh de doc
fscanf(f,"%d %d",&n,&m);//doc so dinh la n va so canh la m
for(i=1;i<=m;i++){//chuyen sang ma tran ke
fscanf(f,"%d %d",&u,&v);
a[u][v]=1;
}
fclose(f);//dong file
}

THUẬT TOÁN TÌM CT VÀ ĐĐ HAMILTON TỪ DANH SÁCH KỀ
void init()//Khởi tạo ma trận kề
{ for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=0;
}

void DocFile(){ //Chuyền từ danh sách kề sang ma trận kề
int i,j ;
FILE *f= fopen("c:/dske.in","r");//mo file do thi de doc
fscanf(f,"%d",&n);//doc so dinh la n
init();
//Dua du lieu tu file dske vao a
5


char S[81];

char dinhke[5]; j=0; int num; int dinh =0;

while (fgets(S,80,f)!=NULL) // doc het tung dong(toi da 80 ky tu) va dua vao chuoi S
{

//viec doc se ket thuc neu den cuoi file thi tra ve gia tri NULL
for ( int i=0; i <=strlen(S); i++) //duyet tu 0 den het chieu dai day S

if (S[i]==' ' || S[i] =='\t' || S[i]=='\n' || S[i]=='\0') //neu ky tu thu i la trang,tab,xuong
dong
{ if (j!=0) // neu j#0 ; i la hang, j la cot
{ dinhke[j]='\0'; j=0; num=atoi(dinhke); //doi tu string sang integer
a[dinh][num]=1;
}
}
else dinhke[j++]=S[i];
dinh++;
}
fclose(f);


}
TÌM THÀNH PHẦN LIÊN THÔNG

1. Khai báo biến:
- Mảng chứa ma trận a[max][max].
- Mảng chuaxet[max]= (true-1: chưa xét, false=0: đã xét)
- Mảng dinhke[max]: chứa các đỉnh kề
- Queue[max]: queue chứa các đỉnh kề nếu dùng thuật toán BFS
- Int sodinh: số đỉnh kề của t
2. Các hàm cần viết:
-

Hàm input
Hàm init_chuaxet()
Ham Duyet_DFS hoặc Duyet_BFS()
void Duyet_DFS(int u)//ham tham mot thanh phan lien thong voi dxp la u
{
printf("%d ",u); //tham dinh u
chuaxet[u]=false; //danh dau u tham roi
for (int v=1;v<=n;v++)//xet cac dinh v tu 1 den n
if (chuaxet[v]==true&&a[u][v]==1)//neu v chua tham va v ke u
Duyet_DFS(v);//goi de qui de tham v
}
6


-

-


Hàm tìm thành phần liên thông
void Tim_tp_lien_thong()
{ int stplt=0;
init_chuaxet();
for(int u=1;u<=n;u++) //lan luot xet cac dinh u tu 1 den n
if (chuaxet[u]==true) //neu u chua xet
{
stplt++;
printf("Thanh phan lien thong thu %d \n",stplt);
Duyet_DFS(u); //tham 1 tp lien thong chua dinh u
printf(" \n");
}
}
Hàm main

CHỨNG MINH ĐỒ THỊ LIÊN THÔNG MẠNH HOẶC YẾU
-

-

Ý tưởng: Đưa thêm biến count vào hàm duyệt DFS-BFS để đếm số phần tử của
thành phần liên thông. Nếu đồ thị có hướng (n đỉnh), sau khi duyệt đủ n đỉnh đều tìm
thấy tplt có n phần tử thì đồ thị liên thông mạnh. Nếu đồ thị không liên thông mạnh
thì sẽ viết thêm hàm chuyển từ ma trận có hướng thành ma trận vô hướng, sau đó
chạy lại hàm Duyệt DFS-BFS, nếu đồ thị liên thông ở cả n đỉnh thì kết luận đồ thiij
liên thông yếu.
Hàm tìm thành phần liên thông
void Tim_tp_lien_thong()
{ int stplt=0; k=0;

init_chuaxet();
for(int u=1;u<=n;u++) //lan luot xet cac dinh u tu 1 den n
if (chuaxet[u]==true) //neu u chua xet
{
stplt++;
printf("Thanh phan lien thong thu %d \n",stplt);
count=1; //reset lại số phần tử trong tplt
Duyet_BFS(u); //tham 1 tp lien thong chua dinh u
printf(" \n");
init_chuaxet(); //tra lai trang thai ban dau de xet tplt tiep theo
if (count!=10) //do thi khong lien thong tai dinh u
{ k++; printf("%d \n",count); //
dinh[k]=u; //khi dinh u do vao mang dinh[k]
}
}
7


}
TÌM CẠNH CẦN BỔ SUNG HOẶC LOẠI BỎ MÀ ĐT VẪN LIÊN THÔNG
-

Ý tưởng: Duyệt BFS-DFS, cạnh đã đi qua thì cho giá trị 2 đỉnh đó bằng 2, sau khi
duyệt cạnh nào có a[i][j]=1 thì loại bỏ.
+ Mỗi thành phần liên thông tìm được , ta sẽ lưu 1 đỉnh của thành phần liên thông đó
vào mảng bosung[stplt]. Cứ n số tplth thì sẽ bổ sung n-1 cạnh để đồ thị liên thông
THUẬT TOÁN TÌM ĐƯỜNG ĐI NGẮN NHẤT DỰA VÀO BẢNG TRƯỚC

-


Ý tưởng: Duyệt BFS-DFS(int u) , lưu vào mảng trước truoc[v]=u
In kết quá: in từ điểm kết thúc đến điểm bắt đầu
i=dkt; printf("%d", i);
while (truoc[i]!=dxp)
{ printf("<--%d",truoc[i]); i=truoc[i]; }
printf("<--%d", dxp);
CÁC THUẬT TOÁN KIỂM TRA SỐ TỰ NHIÊN
int Test_SoNguyenTo(long k){
if (k==1) return 0;
for ( long i=2;i<=sqrt(k);i++)
if (k%i==0) return 0; //khong phai so nguyen to
return 1;
//la so nguyen to
}
int Test_ThuanNghich (long k, int B) {
char s[20], s1[20];
long n;
ltoa(k,s,10); //doi so long k thanh chuoi s voi he co so 10;
strcpy(s1,s); //copy chuoi s sang chuoi s1
strrev(s); //dao nguoc chuoi s
if(strcmp(s,s1)==0) return 1; //neu chuoi s va s1 giong nhau thi tra ve true
else return 0;
}
//Kiem tra tong cac chu so cua k la mot so nguyen to
int Test_Tong(long k) {
int s=0;
//s chua tong cac chu so cua k
while(k!=0){
s=s+ (k%10) ; //lay chu so cuoi cua k cong don vao s
k=k/10;

//tinh lai k bang cach bo chu so cuoi
}
if(Test_Nguyen_To(s)) return 1;
return 0;
}
//Ham tinh tich cac so va kiem tra tinh thuan nghich
int Tich_cac_so_la_thuan_nghich(long k)
{ int t=1; int du;
8


while (du!=0)
{ du=k%10;
k=k/10;
t=t*du;
}
if ((t>=100)&&(t<=999)&&So_thuan_nghich(t,10)) //tich là số có 3 chữ số
return 1;
else return 0 ;
}
//kiem tra tung so trong k khac 0 va moi chu so la so nguyen to
int Test_tungso(long k) {
int du;
while(k!=0){
du = k%10; k=k/10;
if(du==0||Test_Nguyen_To(du)==0) return 0;
}
return 1;
}
//Khong chua 1 so nao do

int Khong_chua_so_r(long k,int r)
{
int du;
while (k!=0)
{ du=k%10;
k=k/10;
if (du==r) return 0;
}
return 1;
}
//Phan tich 1 so thanh thua so nguyen to
void main(){
unsigned long int n =2868336900; int k=0,i=2, OK=1;
do {
if(nguyen_to(n)) { printf("\n Kết quả bước:%d:%ld",++k,n); OK=0;}
else if (n%i==0){printf("\n Kết quả bước:%d: %d",++k,i); n = n/i;}
else i++;
} while(OK);
}

9


CÁC THUẬT TOÁN XỬ LÝ CHUỖI
//Ham sinh chuoi nhi phan ke tiep
void Next_Bit_String(void){
int i=n; //duyet tu cuoi
while(i>0 && B[i]) //lap khi chua tim thay B[i]==0
{ B[i]=0; //gan cac bit sau la 0
i--;} //giam ve truoc

if(i>0) B[i]=1; //tim thay B[i]=0 nen gan 1 cho B[i]
else OK=0; // khong tim thay B[i]=0, cau hinh cuoi nen dung
}
//Kiem tra va Xuat chuoi nhi phan thuan nghich
void Result(void){
int i=1, j=n;
for( ; i < j && B[i]==B[j]; i++, j--) ; //so sanh bit dau va bit cuoi
if(i>=j){
count++; printf("\n Ket qua %d:",count); //xuat man hinh
fprintf(fp,"\n"); //xuong dong khi moi chuoi duoc in ra
for(i=1; i<=n; i++)
{
printf("%3d",B[i]);
fprintf(fp,"%5d",B[i]);
}
}
}
void Duyet(){
Init();
fp=fopen("C:/KETQUA.out","wt"); //mo tap tin, ghi theo van ban hoac nhi phan,
de len cai cu neu co
fprintf(fp," \n"); //de trong 1 dong de khi count xong thi dien vao
while(OK){
Result(); //xuat chuoi nhi phan thuan nghich
Next_Bit_String(); //chuoi nhi phan tiep theo
}
rewind(fp); //quay lai mo file ban dau
fprintf(fp,"%d",count); //ghi count vao dong trong da de danh phia tren
fclose(fp);
}


10


Ketqua.Out

Data.in
7
5

25
10

15

20

25

30

3
0
1
0

35

0
0

1

0
0
1

0
1
0

1
0
0

0
0
0

0
0
0

// Tỉnh tổng
void Result(void){
int i=1, s=0;
for (;i<=n;i++)
s=s+A[i]*B[i];
if (s==b) {
count++;
fprintf(fp,"\n");

for (i=1;i<=n;i++)
fprintf(fp,"%4d", B[i]);
}
}

Data.in
5
5

10

50
15

20

25

Ketqua.Out
3
10
15
5
20
5
10

25
25
15


20

int Tong_cac_phan_tu()
{
s=0;
for(i=1;i<=n;i++)
s=s+A[i]*B[i];
if (s==k) {
count++;
for (i=1;i<=n;i++)//in cac phan tu A[i] tuong ung voi tong s
if (B[i]!=0) //neu B[i]=1 thi in A[i]
fprintf(fp2,"%5d",A[i]);
fprintf(fp2,"\n");
}
}

Data.in
4
6
5

10
3

7

C[i]

5


6

5

A[i]

4

Ketqua.Out
13
FOPT=6+7

1

0

0

1

XOPT<=10. Tìm max FOPT

11


int Gia_tri_toi_uu()
{
int XOPT=0; int s=0;//Gia tri toi uu va tong cua phuong an toi uu
for(i=1;i<=n;i++)

{
s=s+C[i]*D[i]; //Tinh gia tri toi uu
XOPT=XOPT+A[i]*D[i];
}
if ((XOPT<=b) && (s>FOPT))
{ FOPT=s;
for (i=1;i<=n;i++)
E[i]=D[i];
}
}
Data.in
5
3

50

5

15

10

20

25

Ketqua.Out
2
10
15


25

5

25

20

void Tinh_tong_day_con_n_pt()
{
int s=0; int t=0;
for(i=1; i<=N; i++){
s = s + A[i]*C[i]; // Tong day con cua A
t=t+C[i]; // Dem so cac so 1 trong mang C
}
if(s==B && t==K) // s==B : tong day con trong A bang voi B
{
// t==K : So cac so 1 trong C bang voi K
count++;
for(i=1; i<=N; i++) //in chuoi do ra
{
if(C[i])
fprintf(fp2,"%5d ",A[i]);
}
fprintf(fp2,"\n");
//in xong 1 chuoi thi xuong dong
}
}


Data.in
5
3
2
5

15

10

20

Ketqua.Out
7
2
5
2
5
2
5
2
15
2
10
5
15

15
10
20

20
20
20

5

20

10

void Day_con_tang()
12


{
int s=0;
for(i=1; i<=N; i++){
s = s +B[i]; //tính tổng các phần tử của chuỗi con
}
if(s==K) // nếu đủ 3 phần tử
{
int j=1;
for(i=1; i<=N; i++)
if(B[i]) C[j++]=A[i]; //đưa các phần tử đó vào mảng C[j]
if (Day_tang(C,K))
{ count++;
for (int i=1; i<=K;i++)
fprintf(fp2,"%5d",C[i]);
fprintf(fp2,"\n");
}

}
}

CÁC THUẬT TOÁN XỬ LÝ KÝ TỰ
Thống kê và tập hợp số lần xuất hiện của từ
//Khai báo struct của ký tự
typedef struct {
char word[20];
int solan;
} w;
// Tim tu trong mang tu[]
int Find_Word( w *tu, int wn, w temp){
for(int i=1; i<=wn; i++)
if(strcmp(temp.word, tu[i].word)==0)
return(i);
return 0;
}
13


// Tach tu trong file va tap hop lai trong mang tu
int Tim_Tap_Tu( w tu[] ){
w temp; char s[20];
int k;
fp1 = fopen("c:/Data.in","r");
while(!feof(fp1)){ //khi chua den cuoi file
fscanf(fp1,"%s ",s);
strcpy(temp.word, s); //copy tu vua doc duoc vao temp
temp.solan=1; //ghi nhan so lan la 1
k = Find_Word(tu,wn,temp);

if(k==0) {wn++; tu[wn]=temp;} //khong tim thay thi ghi vao mang tu moi
else tu[k].solan++; //neu tim thay thi tang so lan cua tu do len
}
fclose(fp1); return(wn);
}
// In ket qua
void In_Tu(w *tu, int wn){
printf("\n Ket qua: %d",wn);
fp1= fopen("c:/Ketqua.Out","w");
fprintf( fp1, "\n%d",wn);
for(int i=1; i<=wn;i++) {
printf("\n %10s %3d", tu[i].word, tu[i].solan);
fprintf(fp1, "\n %10s %3d", tu[i].word, tu[i].solan);
}
fclose(fp1);
}
int main() {
wn=0; wn= Tim_Tap_Tu(tu);
In_Tu(tu,wn); getch(); }
Số lần ký tự xuất hiện trong file 1 mà không xuất hiện trong file 2
Data1.in
AB AC AD AE AF AG AH
AB AC
AD AE AF AG AH

Data2.in
AB AC AD

AI


CA

CD CE CF CG

CB

Ketqua.out
4
AE
AF
AG
AH

2
2
2
2

Ý tưởng: Tìm số lần của từ xuất hiện trong file 1, file 2 và đưa vào mảng tu1, tu2. Sau đó,
duyệt từng từ trong mảng tu1, nếu không xuất hiện trong file tu2 thì in ra.
void In_ket_qua(w *tu, int wn1)
{
fp2=fopen("C:/ketqua.out","w");
fprintf(fp2,"
\n");
for(i=1;i<=wn1;i++)
if (Find_word(tu2,wn2,tu[i])==0)
{
count++;
fprintf(fp2,"%s %d",tu[i].word,tu[i].solan );

14


}
rewind(fp2);
fprintf(fp2,"%d",count);
fclose(fp2);
}
int main()
{
wn1=Tim_tap_tu(tu1,"C:/data1.in");
wn2=Tim_tap_tu(tu2,"C:/data2.in");
In_ket_qua(tu1,wn1);
}

CÁC THUẬT TOÁN DUYỆT ĐỒ THỊ
mtke.in
5
0
1
1
0
1
0
0
1
0
0

1

0
0
0
1

0
1
0
0
0

0
0
1
0
0

dscanh.out
5
1
1
2
3

4
2
3
4
5


dske.out
5
2
1
1
2
3

3
4
5

void matranke_qua_dske (char *tenfile1,char *tenfile2 ) {
FILE *f, *g;
int n=0;int i,j, so;
if ((f=fopen(tenfile1,"r"))==NULL) return;
if ((g=fopen(tenfile2,"w"))==NULL) return;
fscanf(f,"%d ", &n); //doc n
fprintf (g, "%d",n) ; fprintf (g,"\n"); //ghi so n vao va xuong dong
for (i=1; i<= n; i++)
{ for (j=1; j<=n ; j++)
{ fscanf (f, "%d", &so);
if (so==1) fprintf (g,"%4d", j); //neu doc thay la 1 thi ghi vi tri j
}
fprintf (g,"\n");
}
fclose(f); fclose(g);
}
void matranke_qua_dscanh (char *tenfile1,char *tenfile2 ) {
15



FILE *f, *g; int n=0;int i,j, so;
if ((f=fopen(tenfile1,"r"))==NULL) return;
if ((g=fopen(tenfile2,"w"))==NULL) return;
fscanf(f,"%d ", &n);
fprintf (g,"
\n"); //chừa 1 dòng để in số đỉnh và số cạnh
int socung=0;
for (i=1; i<= n; i++)
for (j=1; j<=n ; j++)
{ fscanf (f, "%d", &so);
if (i<=j)
//vi la vecto vo huong nen loai bo cung i>j
{
socung=socung+so;
if (so==1) fprintf (g,"%4d %4d \n", i, j);
}
}
fclose(f);
rewind (g);
fprintf (g,"%4d %4d", n,socung);fclose(g); }
//CHUYỂN TỪ DANH SÁCH KỀ SANG MA TRẬN KỀ
char S[81]; char dinhke[5]; j=0; int a,num;
int dinh =1;
while (fgets(S,80,f)!=NULL) // doc het tung chuoi (toi da 80 ky tu) va dua vao chuoi
S
{
//viec doc se ket thuc neu den cuoi file thi tra ve gia tri NULL
for ( i=0; i <=strlen(S); i++) //duyet tu 0 den het chieu dai day S

if (S[i]==' ' || S[i] =='\t' || S[i]=='\n' || S[i]=='\0') //neu ky tu thu i la trang,tab,xuong
dong
{ if (j!=0) // neu j#0 ; i la hang, j la cot
{ dinhke[j]='\0'; j=0; num=atoi(dinhke); //doi tu string sang integer
G[dinh][num]=1;
}
}
else dinhke[j++]=S[i];
dinh++;
//printf("%5d\n",atoi(S)); getch();
}
fclose(f);
//CHUYỂN MA TRẬN KỀ G SANG DANH SÁCH CẠNH
fprintf (g, "
\n");
int socung=0;
for (i=1; i<= n; i++)
for (j=i+1; j<=n ; j++)
{
16


socung=socung+G[i][j];
if (G[i][j]==1) fprintf (g,"%4d %4d \n", i, j);
}
rewind(g);
fprintf (g,"%5d %5d\n", n, socung);
fclose(g);

dscanh.in

5
1
1
2
2
3
3
4
5

dske.out
8
2
3
1
4
1
5
2
3

5
2
1
1
2
3

mtke.out
3

4
5

5
0
1
1
0
0

1
0
0
1
0

1
0
0
0
1

0
1
0
0
0

0
0

1
0
0

//Doi tu dscanh sang G
for (i=1; i<= m; i++)
{
fscanf(fp1,"%d %d",&u,&v); //doc va dua du lieu tu dscanh vao bien u va v
G[u][v]=G[v][u]=1; //gan gia tri G tai toa do u,v=1
}
fclose(fp1);
//xuat G sang ma tran ke
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
fprintf(fp2,"%4d ",G[i][j]);
fprintf(fp2,"\n");
}
fclose(fp2);
//xuat ket qua sang danh sach ke
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
if(G[i][j]==1)
fprintf(fp3,"%4d",j);
fprintf(fp3,"\n");
}
17



fclose(fp3);

void ThuaSoNgTo( long n) {
int i=2;
while (n >1)
{ while (n %i !=0 ) i++;
printf ("%8d", i);
n = n/i;
}
}
void CacSoHoanHao(long n) {
long A[5]={6,28,496,8128,33550336};
for (int i =0 ; i< 5; i++)
if (A[i] < n) printf ("%ld ", A[i]);
}
//Tao day so ngau nhien
const int n=31;const int m =30;
void Init (int *A,int n) {
for (int i=1; i<=n ; i++) A[i]=i;
}
int randInt(int a, int b) {
return a+ rand() % (b-a+1);
}
void Hoanvi (int &a, int &b) {
int t = a; a = b ; b=t;
}
void Lietke(int *A,int m) {
for (int i=1; i<=m ; i++)
printf ("%8d",A[i]);
}

int main () {
int *A = new int [n+1];
Init (A,n);
int i, j;
//randomize();
for (i=1; i<=m ; i++) {
j= randInt(i, n);
Hoanvi (A[i], A[j]) ;
}
18


Lietke(A, m); getch(); }
int c[max][max];//bang chi phi; c[i][j] la chi phi di tu tp i den tp j
int x[max];//mang chua lo trinh toi uu tam thoi
int xopt[max];//mang chua lo trinh toi uu thuc su: x1->x2->...->xn->x1
int cost=vocung;//chi phi toi uu
int sum=0;//chua tong chi phi di tu x[1] den x[i]
int tham[max];
//Ham duyet
void Duyet(int t)
{
for (int j=1;j<=n;j++)
if (tham[j]==0&&c[x[t-1]][j]!=0) //neu j chua tham va ke voi tp x[i-1]
{ x[t]=j; //chon tp tiep theo la j
tham[j]=1;
sum=sum+c[x[t-1]][j];//tinh tong chi phi di tu i den j
printf("%d %d %d ",j,t,sum);
if (t==n)
{ if (c[x[n]][x[1]]!=0) //neu tp cuoi ke voi tp xuat phat

if (sum+c[x[n]][x[1]]{ for (int k=1;k<=n;k++) xopt[k]=x[k]; getch();
cost=sum+c[x[n]][x[1]]; //tong chi phi tim duoc cuoi cung
}
}
else if (sumtham[j]=0; sum=sum-c[x[t-1]][j];
}
}
void Lo_trinh_toi_uu()
{ for(int i=1;i<=n;i++) tham[i]=0;
x[1]=dxp;
tham[dxp]=1;
Duyet(2);
}
void GhiFile()
{
fp=fopen("c:/lotrinh.out","w");//mo file lotrinh de ghi
fprintf(fp,"%4d\n",cost);//ghi chi phi nho nhat
for(int i=1;i<=n;i++)//ghi x[1]->x[2]->...x[n]->
fprintf(fp,"%4d ->",xopt[i]);
fprintf(fp,"%4d",xopt[1]);//ghi x[1]
fclose(fp);
}

matran.in
6
10
34
57

29
28
15

64
20
49
21
16
12

57
19
40
46
11
15

29
30
16
26
21
48

18
16
11
21
21

37

15
12
19
18
37
30

ketqua.out
1
1
2
6
3
4
4
5
5
3
6
2

10
12
16
21
11
12


19


//Ban dau cac cong viec deu chua duoc chon
void Init (int n)
{
for (int i=1; i<=n; i++) B[i]=1; //111111
}
void Try ( int i, int n)
{ for (int j=1; j <= n; j++ )
if (B[j]) //neu cong viec B[j] chua chon
{ X[i]=j; //Mang chua thu tu cong viec
P = P +C[i][j]; //tinh tong chi phi thuc hien den cong viec do
B[j]=0; //da chon viec do roi
if (i==n) // da sap xep du n cong viec
{if ( P < FOPT)
{ FOPT = P; //Cap nhat gia tri toi uu
for(int k=1; k<=n; k++) // Cap nhat PATU
XOPT[k] = X[k];
}
}
else Try (i+1,n);
B[j]=1;
P = P -C[i][j];
}
}
void Ketqua()
{
fp=fopen("c:/ketqua.out","w");
fprintf(fp,"%d\n",FOPT);

for (int i=1;i<=n;i++)
{ printf("%4d %4d %4d\n",i,XOPT[i],C[i][XOPT[i]]);
fprintf(fp,"%4d %4d %4d\n",i,XOPT[i],C[i][XOPT[i]]);
}
fclose(fp);
}
matran.in
6
10
34
57
29
28
15

64
20
49
21
16
12

57
19
40
46
11
15

29

30
16
26
21
48

18
16
11
21
21
37

15
12
19
18
37
30

ketqua.out
1
1
2
6
3
4
4
5
5

3
6
2

10
12
16
21
11
12

20


//Ban dau cac cong viec deu chua duoc chon
void Init (int n)
{
for (int i=1; i<=n; i++) B[i]=1; //111111
}
void Try ( int i, int n)
{ for (int j=1; j <= n; j++ )
if (B[j]) //neu cong viec B[j] chua chon
{ X[i]=j; //Mang chua thu tu cong viec
P = P +C[i][j]; //tinh tong chi phi thuc hien den cong viec do
B[j]=0; //da chon viec do roi
if (i==n) // da sap xep du n cong viec
{if ( P == s)
{ count++; //Cap nhat gia tri toi uu
for(int k=1; k<=n; k++) // Cap nhat PATU
{ XOPT[k] = X[k];

printf("%3d",XOPT[k]);
fprintf(fp1,"%3d",XOPT[k]);
}
printf("\n");
fprintf(fp1,"\n");
}
}
else Try (i+1,n);
B[j]=1;
P = P -C[i][j];
}
}

21



×