Professional Documents
Culture Documents
Backtrack
Backtrack
Backtrack
1. 8 queen
#include<bits/stdc++.h>
using namespace std;
long long a[1000]={0},b[1000]={0},c[1000]={0},mm[1000][1000],n,max=0;
void show(){
/*long sum=0;
for(long i=0;i<n;i++){
for(long j=0;j<n;j++){
if(mm[i][j]==1) sum+=i+j+2;
}
}
if(sum>max) max=sum;*/
for(long i=0;i<n;i++){
for(long j=0;j<n;j++){
if(mm[i][j]==0) cout<<"x";else cout<<"Q";
}cout<<'\n';
}cout<<'\n';
}
void back(long y){
if(y==n){
show();return;
}
for(long x=0;x<n;x++){
if(a[x]==0&&b[x+y]==0&&c[x-y]==0){
mm[x][y]=1;
a[x]=b[x+y]=c[x-y]=1;
back(y+1);
mm[x][y]=0;
a[x]=b[x+y]=c[x-y]=0;
}
}
}
int main(){
cin>>n;back(0);
}
2.Cho n (n≤10) số nguyên dương a1, a2,…, aN (ai<109).
Tìm số nguyên dương m nhỏ nhất sao cho m không phân
tích được dưới dạng tổng của một số các số (mỗi số sử
dụng không quá một lần) thuộc n số trên. Ví dụ: n=4,
a={1,2,3,6} thì kết quả là 13. Input : Dòng đầu tiên chứa
số N. Dòng tiếp theo chứa N số. Output : Một dòng chứa
kết quả
#include<bits/stdc++.h>
using namespace std;
bool used[200];
long n,a[10000],b[1000];long z=0;
void show(){
long tong=0;
for(long i=0;i<n;i++){
if(used[i]==1) tong+=a[i];
}
b[z]=tong;z++;
}
void back(long pos){
if(pos==n){
show();return ;
}
used[pos]=0;
back(pos+1);
used[pos]=1;
back(pos+1);
}
int main(){
cin>>n;
for(long i=0;i<n;i++) cin>>a[i];back(0);
sort(b,b+z);
b[z] = 1e9+7;
for(int i = 0; i < z; i++){
if(b[i] + 1 < b[i+1]){
cout << b[i]+1;
break;
}
}
}
3.chuyen string sang so
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;cin>>s;
long curendigit,digitvalu,digitsum,remainder;
digitsum=0;
for(curendigit=0;curendigit<s.length();curendigit++){
digitvalu=s[curendigit]-'0';
digitsum+=digitvalu;
}
remainder=digitsum%9;
cout<<remainder;
}
4. knapsack(dp)
#include<bits/stdc++.h>
using namespace std;
int main(){
long w,n;
cin>>w>>n;
long a[n+1],v[1000][1000],b[n+1];
for(long i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
for(long i=0;i<=n;i++){
for(long j=0;j<=w;j++){
if(i==0||j==0) v[i][j]=0;
else if(a[i]<=w){
v[i][j]=max(b[i]+v[i-1][j-a[i]],v[i-1][j]);
}else v[i][j]=v[i-1][j];
}
}
cout<<v[n][w];
}
5.kiểm tra số fibonacci
#include <stdio.h>
#include <math.h>
int main()
{
float a;
float A,B;
scanf("%f",&a);
A=sqrt(5*a*a+4);
B=sqrt(5*a*a-4);
if(A == (int) A)
{
printf("YES");
}
else if(B == (int)B)
{
printf("YES");
}
else
{
printf("NO");
}
}
6. hoán vị giai thừa
#include <bits/stdc++.h>
using namespace std;
bool used[20];
show(int n, int a[])
{
for(int i=0; i<n; i++) cout << a[i] << " ";
cout << endl;
}
void backtrack(int pos, int a[], int n)
{
if(pos==n) {show(n, a); return;}
for(int i=0; i<n; i++)
{
if(!used[i])
{
a[pos]=i+1;
used[i]=true;
backtrack(pos+1, a, n);
used[i]=false;
}
}
}
int main()
{
int n;
cin >> n;
int a[n];
backtrack(0, a, n);
}
7. bài toán mã đi tuần
#include <stdio.h>
#define n 8
int find(int x,int y,int dem,int sol[n][n],int xtt[n],int ytt[n]);
void show(int sol[n][n]){int i,j;
for( i=0;i<n;i++){
for( j=0;j<n;j++)
printf(" %2d ",sol[i][j]);
printf("\n");}
}
bool issafe(int x,int y,int sol[n][n]){
return(x>-1 && x<n && y>-1 && y<n && sol[x][y]==-1);
}
bool kiemtra(){
int sol[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
sol[i][j]=-1;
for(k=0;k<8;k++){
xnext=x+xtt[k];
ynext=y+ytt[k];
if(issafe(xnext,ynext,sol)){
sol[xnext][ynext]=dem;
if(find(xnext,ynext,dem+1,sol,xtt,ytt)==true) return true;
else sol[xnext][ynext]=-1;}
}
return false;
}
int main(){
kiemtra();return 0;
}
8.qui hoach dong tinh cach phan tich so nguyen
duong
#include<bits/stdc++.h>
using namespace std;
int main(){
long n;
long f[100][100];
f[0][0]=1;
cin>>n;
for(long m=1;m<=n;m++){
for(long v=0;v<=n;v++){
if(v<m){
f[m][v]=f[m-1][v];}
else f[m][v]=f[m-1][v]+f[m][v-m];
}}
cout<<f[n][n];
}
Backtrack tinh so cach phan tich
#include<bits/stdc++.h>
using namespace std;
void back(long i,long n,long x[],long t[]){
for(long j=x[i-1];j<=n-t[i-1];j++){
x[i]=j;
t[i]=t[i-1]+j;
if(n==t[i-1]+x[i]){
for(long k=1;k<=i;k++){
cout<<x[k]<<" ";
}cout<<'\n';
}else
back(i+1,n,x,t);
}
}
int main(){
long n;cin>>n;long x[n+1],t[n+1];
x[0]=1;t[0]=0;
back(1,n,x,t);
}
9 coinchange
int count( int S[], int m, int n )
{
//we need a two dimensional matrix to store the result
int table[m+1][n+1];
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(S[i-1]>j)
{
table[i][j]=table[i-1][j];
else
{
table[i][j]=table[i-1][j]+table[i][j-(i-1)];
}
}
}
return table[m][n];
}
// C++ program for coin change problem.
#include<bits/stdc++.h>
// total count
table[i][j] = x + y;
}
}
return table[n][m - 1];
}
Backtrack thật sự
#include <bits/stdc++.h>
using namespace std;
#define V 4
void tsp(int graph[][V], vector<bool>& v, int currPos,
int n, int count, int cost, int& ans)
{
if (count == n && graph[currPos][0]) {
ans = min(ans, cost + graph[currPos][0]);
return;
}
for (int i = 0; i < n; i++) {
if (!v[i] && graph[currPos][i]) {
v[i] = true;
tsp(graph, v, i, n, count + 1,
cost + graph[currPos][i], ans);
v[i] = false;
}
}
};
int main()
{
int n = 4;
int graph[][V] = {
{ 0, 10, 15, 20 },
{ 10, 0, 35, 25 },
{ 15, 35, 0, 30 },
{ 20, 25, 30, 0 }
};
vector<bool> v(n);
for (int i = 0; i < n; i++)
v[i] = false;
v[0] = true;
int ans = INT_MAX;
tsp(graph, v, 0, n, 1, 0, ans);
cout << ans;
}
PERMUTATION
#include <bits/stdc++.h>
using namespace std;
#define V 4
vector<int> vertex;
for (int i = 0; i < V; i++)
if (i != s)
vertex.push_back(i);
int min_path = INT_MAX;
do {
// update minimum
min_path = min(min_path, current_pathweight);
} while (next_permutation(vertex.begin(), vertex.end()));
return min_path;
}
void show(){
bool check=true;
if(count()!=n) check=false;
for(long i=0;i<2*n;i++){
if(sum(i)<0) {check=false;break;}
}
if(check){
for(long i=0;i<2*n;i++){
if(a[i]==1) cout<<"(";else cout<<")";
}
cout<<'\n';
}
}
void back(long pos){
if(pos==2*n){
show();return;
}
a[pos]=1;
back(pos+1);
a[pos]=-1;
back(pos+1);
}
int main(){
cin>>n;back(0);
}
12. CHỈNH HỢP LẶP
#include<bits/stdc++.h>
using namespace std;
long n,m,a[1000];
void show(){
for(long i=1;i<=m;i++){
cout<<a[i]<<" ";
}
cout<<'\n';
}
void back(long i){
for(long j=1;j<=n;j++){
a[i]=j;
if(i==m){
show();
}
else back(i+1);
}
}
int main(){
cin>>n>>m;back(1);
}
In 2 3
Out 1 1 1
112
121
122
211
212
221
222
13. CHINH HOP KHONG LAP
#include<bits/stdc++.h>
using namespace std;
long n,m,a[1000],d[100]={0};
long x[100],t[100],n;
float a,b;
a=sqrt(5*n*n+4);
b=sqrt(5*n*n-4);
return 0;
for(long j=x[i-1];j<=n-t[i-1];j++){
x[i]=j;
t[i]=t[i-1]+j;
if(t[i]==n){
bool check=1;
sort(x,x+i);
for(long m=1;m<i;m++){
if(x[m]==x[m+1]){
check=0;break;
if(check==1) {
for(long k=1;k<=i;k++){
if(fibo(x[k])==0) {
check=0;break;}
}
if(check==1) {
for(long k=1;k<=i;k++){
cout<<x[k]<<" ";
cout<<'\n';
else back(i+1);
int main(){
x[0]=1;t[0]=0;
cin>>n;back(1);
C2;
#include<bits/stdc++.h>
if(n==1||n==2) return 1;
return fi(n-1)+fi(n-2);
int main(){
long n;
cin>>n;
while(n>0){
long i=1;
while(fi(i)<=n) i++;
if(i<=n)cout<<fi(i-1)<<"+";
else cout<<fi(i-1)
;// tất cả đều qui về th 4 và 6 khi đó n=1 thì khi i>1 thì cout<<fi(i-1)=F=fi2=1
n-=fi(i-1);
cout<<"="<<"n";
long n,lolo;
bool d[100];
long fi[100];
if(n==0){
cout<<i-1;return;
for(long j=1;j<=lolo;j++){
if(!d[j]&&n>=fi[j]){
d[j]=true;
n-=fi[j];
back(i+1);
d[j]=false;
n+=fi[j];
int main(){
cin>>n;long i=2;
fi[1]=1;fi[2]=1;
while(fi[i]<n) {i++;fi[i]=fi[i-1]+fi[i-2];}
lolo=i;
back(0);
return tong;
long dem=0;
for(long i=0;i<n;i++){
if(a[i]==1) dem++;
return dem;
long maxx=0;
long dem=0;
for(long i=0;i<n;i++){
if(a[i]==1) dem++;
else{
if(dem>maxx) maxx=dem;
dem=0;
return maxx;
bool check=true;
if(check1(n,a)*2!=n) check=false;
for(long i=0;i<n;i++){
if(sum(i,a)<0) {
check=false;break;
if(check2(n,a)!=k) check=false ;
if(check){
for(long i=0;i<n;i++){
if(a[i]==1) cout<<"(";
else cout<<")";
cout<<'\n';
if(pos==n){
show(n,a,k);return;
a[pos]=1;
back(pos+1,a,n,k);
a[pos]=-1;
back(pos+1,a,n,k);
int main(){
long n,k;
cin>>n>>k;
long a[2*n+1];
back(0,a,n,k);
18.Hoan vi sau
#include<bits/stdc++.h>
int main() {
string a;cin>>a;
sort(a.begin(),a.end());
do{
cout<<a<<" ";
}while(next_permutation(a.begin(),a.end()));
C222222
#include <bits/stdc++.h>
bool used[20];
cout << a;
if(!used[i])
used[i]=true;
backtrack(pos+1,s,a, n);
used[i]=false;
int main()
int n;
string s,a;
cin>>s; n=s.length();
backtrack(0,s,a,n);
}
19. GIẢ THIẾT N LÀ SỐ NGUYÊN DƯƠNG. SÔ NGUYÊN M
LÀ TỎNG CỦA N VỚI CÁC CHỮ SỐ CỦA NÓ. N ĐƯƠC GỌI
LÀ NGUỒN CỦA M. VÍ DỤ VỚI N =245 THÌ M=2+4+5+245.
CÓ SỐ KHÔNG CÓ NGUỒN CÓ SỐ NHIỀU NGUỒN. SỐ 216
CÓ 2 NGUỒN LÀ 198 VÀ 207. CHO SỐ M TÌM NGUỒN NHỎ
NHẤT CỦA M.NẾU KHÔNG CÓ NGUỒN IN 0.
#include<bits/stdc++.h>
long tong=0;
while(n>0){
tong+=n%10;
n/=10;
return tong;
long x=0;
while(n>0){
x++;
n/=10;
return x;
int main(){
long n;
cin>>n;
for(long i=n-dem(n)*9;i<n;i++){
if(i+tong(i)==n) {
cout<<i;return 0;
cout<<0;
20 quả cân
long i=0;
while(pow(3,i)<=n){
i++;
//if(n%3==0)( với n chia 3 dư 2 thì thêm 3^0 vào bên n rồi thực hiện như th1)(với n
chia 3 dư 1 thì thêm 3 và 3^2 vào bên n rồi thực hienj như th1//
if(n==pow(3,i-1)){
if(n%3==2 )cout<<"benphai"<<n<<'\n';
else {
cout<<"benphai"<<n<<'\n';
cout<<"bentrai:"<<pow(3,i-1)<<" ";
n-=pow(3,i-1);
long k=0;
while(n!=pow(3,k)) k++;
cout<<pow(3,k);
// if(digit==1)
// return (y==1)?y:0;
int count=0;
while(digit){
int x = digit%10;
digit = digit/10;
count += (x==y);
return count;
int count = 0;
for(int i=1;i<=x;i++){
count+=CountOfTwo(i,y);
return count;
int main() {
int x=300,y=3;
// int x=25,y=2;
cout<<GetOccurence(x,y);
return 0;
}
THẺ ATM
#include<bits/stdc++.h>
long t[100],n,s,maxx=0;
long cbest=1000,sum=0,c;
void update(){
if(sum==s&&c<cbest){
cbest=c;
if((c+(s-sum)/maxx)>=cbest) return;
for(long i=0;i<2;i++){
sum+=i*t[pos];
c+=i;
if(i==n){
update();
}else back(pos+1);
sum-=i*t[pos];
c-=i;
int main(){
cin>>n>>s;
back(0);
cout<<cbest;
vector<int> triangle;
int main(){
int m;cin>>m;
for(long i=0;i<m*(m+1)/2;i++){
int current;
cin>>current;
triangle.push_back(current);
for(long n=m-1;n>0;n--){
for(long k=n*(n-1)/2;k<n*(n+2)/2;k++){
triangle[k]*=max(triangle[k+n],triangle[k+n+1]);
cout<<triangle[0];
Có N quân domino xếp thành hàng như hình vẽ. Mỗi quân domino được chia thành
22.
hai phần, phần trên và phần dưới. Trên mặt mỗi phần có các chấm, số chấm từ 0 đến 6. Ở
hình vẽ trên, tổng số chấm ở phần trên của N quân domino là 4+4+4+4=16; tổng số chấm ở
phần dưới của N quân domino là 3+2+1+0=6. Độ chênh lệch giữa tổng trên và tổng dưới là
│16-6│= 10. Với mỗi quân domino, có thể quay 1800C để phần trên trở thành phần dưới và
khi đó độ chênh lệch có thể thay đổi. Ví dụ, nếu ta đảo vị trí quân đomino ngoài cùng bên
phải, thì độ chênh lệch là 2.
Năm mới. Cơ Hội mới. Thách Thức mới. Thắng Lợi mới !
Trang 4
Cho trước N quân đomino, hãy xác định số phép quay ít nhất để độ chênh lệch giữa phần
trên và phần dưới là nhỏ nhất. Input : Dòng đầu là số N. N dòng tiếp theo ghi 2 số từ 0 đến
6, là số chấm mặt trên và mặt dưới của các quân domino tương ứng. Output: Độ chênh lệch
nhỏ nhất.
#include<bits/stdc++.h>
bitset<30> used;
long n,a[100],b[100];
long minn=999999;
void show(){
long sum1=0,sum2=0;
for(long i=0;i<n;i++){
if(used[i]==1){
swap(a[i],b[i]);
sum1+=a[i],sum2+=b[i];
}cout<<sum1<<" "<<sum2<<'\n';
if(minn>sum1-sum2&&sum1-sum2>=0) minn=sum1-sum2;
if(pos==n){
show();return;
used[pos]=1;
back(pos+1);
used[pos]=0;
back(pos+1);
int main(){
cin>>n;
for(long i=0;i<n;i++){
cin>>a[i]>>b[i];
back(0);cout<<minn;
#include<bits/stdc++.h>
bitset<100> used1;
bitset<100> used2;
long a[1000][1000],n,m;
long minn=99999;
void show(){
long sum=0,dem=0;
for(long i=0;i<n;i++){
if(used1[i]==1){
dem++;
for(long j=0;j<m;j++){
a[i][j]=0;
for(long j=0;j<m;j++){
if(used2[j]==1){
dem++;
for(long i=0;i<n;i++){
a[i][j]=0;
}
for(long i=0;i<n;i++){
for(long j=0;j<m;j++){
sum+=a[i][j];
if(sum==0){if(dem<minn) minn=dem;}
if(pos==n){
if(ops==m){
show();return;
used2[ops]=1;
back(pos,ops+1);
used2[ops]=0;
back(pos,ops+1);
used1[pos]=1;
back(pos+1,ops);
used1[pos]=0;
back(pos+1,ops);
int main(){
cin>>n>>m;
for(long i=1;i<=n;i++){
for(long j=1;j<=m;j++){
cin>>a[i][j];
back(0,0);cout<<minn;