#include<stdio.h> int miro[10][10],chk[11][11]={0},path[100][2]; int maxpath[100][2],minpath[100][2]; int max=-9999,min=9999; int row,col,st_x,st_y,maxcnt,mincnt,maxsum,minsum; FILE *fp,*fp1; void back(int x,int y,int sum,int cnt){ int i,j; path[cnt][0]=x; path[cnt][1]=y; chk[x][y]=1; if(x==row && y==col){ if(sum>max){ for(i=1;i<=cnt;i++){ maxpath[i][0]=path[i][0]; maxpath[i][1]=path[i][1]; } max=sum; maxcnt=cnt; } else if(sum<min){ for(i=1;i<=cnt;i++){ minpath[i][0]=path[i][0]; minpath[i][1]=path[i][1]; } min=sum; mincnt=cnt; } chk[x][y]=0; } else{ if(!chk[x][y+1]) back(x,y+1,miro[x][y+1]+sum,cnt+1); if(!chk[x+1][y]) back(x+1,y,miro[x+1][y]+sum,cnt+1); if(!chk[x][y-1]) back(x,y-1,miro[x][y-1]+sum,cnt+1); if(!chk[x-1][y]) back(x-1,y,miro[x-1][y]+sum,cnt+1); chk[x][y]=0; } } main(){ int i,j; fp=fopen("input.txt","r"); fp1=fopen("output.txt","w"); fscanf(fp,"%d %d",&row,&col); for(i=1;i<=row;i++){ for(j=1;j<=col;j++){ fscanf(fp,"%d",&miro[i][j]); } } fscanf(fp,"%d %d",&st_x,&st_y); for(i=0;i<=row+1;i++){ for(j=0;j<=col+1;j++){ if(i==0 || i==row+1 || j==0 || j==col+1) chk[i][j]=1; } } back(st_x,st_y,miro[st_x][st_y],1); fprintf(fp1,"최대경로:"); for(i=1;i<=maxcnt;i++) fprintf(fp1,"(%d,%d)",maxpath[i][0],maxpath[i][1]); fprintf(fp1,"\n최대합 : %d\n",max); fprintf(fp1,"최소경로:"); for(i=1;i<=mincnt;i++) fprintf(fp1,"(%d,%d)",minpath[i][0],minpath[i][1]); fprintf(fp1,"\n최소합 : %d\n",min); }
전체 글
- 백트래킹 - 미로 2009.07.29
- 부분집합의 합 2009.07.29
- 장기판에 상놓기 - 가지수 2009.07.29
백트래킹 - 미로
2009. 7. 29. 21:10
부분집합의 합
2009. 7. 29. 21:08
#include <iostream> #include <fstream> #include <string> using namespace std; ifstream fin("input.txt"); ofstream fout("output.txt"); int a[5]={5,6,10,11,16},check[100]={0}; //오름차순 정렬된 데이터. int n=5,find=21; //n원소의 수, find 목표 수 void subsum(int p,int s){ int promising; promising= (p<=n) && (s==find || s+a[p]<=find); //promising 유망 판별 변수, 가지치기 if(promising){ if(s==find){ for(int i=0;i<n;i++){ if(check[i]) cout << a[i] << " "; } cout << endl; } else{ check[p]=1; subsum(p+1,s+a[p]); //현재 a[p]를 포함시키고 호출 check[p]=0; subsum(p+1,s); // 포함시키지 않고 호출 } } } void main(){ subsum(0,0); }
장기판에 상놓기 - 가지수
2009. 7. 29. 21:07
#include <iostream> #include <fstream> #include <string> using namespace std; ifstream fin("input.txt"); ofstream fout("output.txt"); int chky[8]={2,3,3,2,-2,-3,-3,-2}; int chkx[8]={3,2,-2,-3,-3,-2,2,3}; int chkt[8][8]={0}; int cnt=0,row,col; void janggi(int p,int k){ if(p>=row){ cnt++; } else{ for(int i=0;i<col;i++){ int flag=1; if(chkt[p][i]) flag=0; if(flag){ for(int j=0;j<8;j++){ if(p+chkx[j]>=0 && p+chkx[j]< row && i+chky[j]>=0 && i+chky[j]< col) if(chkt[p+chkx[j]][i+chky[j]]==0) chkt[p+chkx[j]][i+chky[j]]=p+1; } janggi(p+1,i); for(j=0;j<8;j++){ if(p+chkx[j]>=0 && p+chkx[j]< row && i+chky[j]>=0 && i+chky[j]< col) if(chkt[p+chkx[j]][i+chky[j]]==p+1) chkt[p+chkx[j]][i+chky[j]]=0; } } } } } void main(){ fin >> row >> col; janggi(0,0); fout << cnt; }