Backtrack

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 28

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;

int xtt[8] = { 2, 1, -1, -2, -2, -1, 1, 2 };


int ytt[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
sol[0][0]=0;
if(find(0,0,1,sol,xtt,ytt)==false) {
printf("no solution");return false;
}
else show(sol);
return true;
}
int find(int x,int y,int dem,int sol[n][n],int xtt[n],int ytt[n]){
if(dem==n*n){
return true;
}
int xnext,ynext,k;

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];

// Initialize all table values as 0


memset(table, 0, sizeof(table));

// Base case (If given value is 0)


for(int i=0;i<m;i++)
{table[0][i] = 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>

using namespace std;

int count( int S[], int m, int n )


{
int i, j, x, y;

// We need n+1 rows as the table


// is constructed in bottom up
// manner using the base case 0
// value case (n = 0)
int table[n + 1][m];

// Fill the enteries for 0


// value case (n = 0)
for (i = 0; i < m; i++)
table[0][i] = 1;

// Fill rest of the table entries


// in bottom up manner
for (i = 1; i < n + 1; i++)
{
for (j = 0; j < m; j++)
{
// Count of solutions including S[j]
x = (i-S[j] >= 0) ? table[i - S[j]][j] : 0;

// Count of solutions excluding S[j]


y = (j >= 1) ? table[i][j - 1] : 0;

// total count
table[i][j] = x + y;
}
}
return table[n][m - 1];
}

10. TRAVEL SALEMAN


#include<bits/stdc++.h>
using namespace std;
long x[100],t[100],a[100],n,used[100]={1}, c[100][100];long dem;
long minspending=10e+7;
void show(long k){
dem=k;
for(long i=1;i<=k;i++){
a[i]=x[i];
}
}
void back(long i){
for(long j=2;j<=n;j++){
if(used[j]==1){
x[i]=j;
t[i]=t[i-1]+c[x[n]][j];
if(t[i]<minspending){
if(i==n){
if(t[n]+c[x[n]][1]<minspending){
minspending=t[n]+c[x[n]][1];
show(i);
}
}else{
used[j]=0;
back(i+1);
used[j]=1;
}
}
}
}
}
int main(){
cin>>n;
for(long i=1;i<=n;i++) for(long j=1;j<=n;j++) cin>>c[i][j];
t[1]=0;
back(2);cout<<minspending<<'\n';
for(long i=1;i<=dem;i++) cout<<a[i];
}
INPUT
4
0 10 15 20
10 0 35 25
15 35 0 30
20 25 30 0
OUT<<80

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 {

// store current Path weight(cost)


int current_pathweight = 0;

// compute current path weight


int k = s;
for (int i = 0; i < vertex.size(); i++) {
current_pathweight += graph[k][vertex[i]];
k = vertex[i];
}
current_pathweight += graph[k][s];

// update minimum
min_path = min(min_path, current_pathweight);
} while (next_permutation(vertex.begin(), vertex.end()));

return min_path;
}

// driver program to test above function


int main()
{
// matrix representation of graph
int graph[][V] = { { 0, 10, 15, 20 },
{ 10, 0, 35, 25 },
{ 15, 35, 0, 30 },
{ 20, 25, 30, 0 } };
int s = 0;
cout << travllingSalesmanProblem(graph, s) << endl;
return 0;
}11. CATALAN CÓ RẤT NHIỀU ỨNG DỤNG BÀI ĐIỀN
DẤU”()” BÀI ĐIỀN TỪ DIC
#include<bits/stdc++.h>
using namespace std;
long n,a[1000];
long sum(long pos){
long tong=0;
for(long i=0;i<pos;i++){
tong+=a[i];
}
return tong;
}
long count(){
long dem=0;
for(long i=0;i<2*n;i++){
if(a[i]==1) dem++;
}return dem;
}

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};

void back(long i){


for(long j=1;j<=n;j++){
if(d[j]==0){
a[i]=j;
d[j]=1;
if(i==m){
for(long i=1;i<=m;i++){
cout<<a[i]<<" ";
}
cout<<'\n';
}
back(i+1);
d[j]=0;
}
}
}
int main(){
cin>>n>>m;back(1);
}
In 3 2
Out 1 2
13
21
23
31
32
14. TO HOP
#include<bits/stdc++.h>
using namespace std;
long n,x[1000],k;
void back(long i){
for(long j=x[i-1]+1;j<=n-k+i;j++){
x[i]=j;
if(i==k){
for(long i=1;i<=k;i++) cout<<x[i]<<" ";cout<<'\n';
}
else back(i+1);
}
}
int main(){
x[0]=0;
cin>>k>>n;back(1);
}
15. PHÂN TÍCH N THÀNH TỔNG CÁC SỐ fibonacci
#include<bits/stdc++.h>

using namespace std;

long x[100],t[100],n;

long fibo(long n){

float a,b;

a=sqrt(5*n*n+4);

b=sqrt(5*n*n-4);

if(a==long(a)||b==long (b)) return 1;

return 0;

void back(long i){

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>

using namespace std;

long fi(long n){

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";

16. CÓ BAO NHÊU CÁCH PHÂN TÍCH 1 SỐ RA fibo// đag fix


#include<bits/stdc++.h>

using namespace std;

long n,lolo;

bool d[100];

long fi[100];

void back(long i){

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);

17. IN RA DẤU ĐÓNG MỞ NGOẶC CÓ ĐỘ SÂU


#include<bits/stdc++.h>

using namespace std;

long sum(long n,long a[]){

long tong =0;

for(long i=0;i<n;i++) tong+=a[i];

return tong;

long check1(long n,long a[]){

long dem=0;

for(long i=0;i<n;i++){

if(a[i]==1) dem++;

return dem;

long check2(long n,long a[]){

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;

void show(long n,long a[],long k){

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';

void back(long pos,long a[],long n,long k){

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>

using namespace std;

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>

using namespace std;

bool used[20];

void show(int n,string a)

cout << a;

cout << endl;


}

void backtrack(int pos,string s,string a,int n)

if(pos==n) {show(n,a); return;}

for(int i=0; i<n; i++)

if(!used[i])

if(a.size() <= pos) a+=s[i];

else a[pos] = s[i];

// code cũ : a[pos] = s[i] -> Đã có phần tử nào


của a đâu mà so sánh ???

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>

using namespace std;

long tong(long n){

long tong=0;

while(n>0){

tong+=n%10;

n/=10;

return tong;

long dem(long n){

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

void tinh(long 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);

20. ĐÁNH SỐ TRANG SÁCH TỪ 1 ĐẾN N. HỎI SỬ DỤNG


BAO NHIÊU SỐ 1 SỐ 2 .. SỐ 9
#include <iostream>

using namespace std;

int CountOfTwo(int digit,int y){

// 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 GetOccurence(int x,int y){

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;
}

21 CHỌN SỐ TỜ TIỀN ÍT NHẤT

THẺ ATM

#include<bits/stdc++.h>

using namespace std;

long t[100],n,s,maxx=0;

long cbest=1000,sum=0,c;

void update(){

if(sum==s&&c<cbest){

cbest=c;

void back(long pos){

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;

for(long i=0;i<n;i++) cin>>t[i];sort(t,t+n);maxx=t[n-1];

back(0);
cout<<cbest;

21. TAM GIÁC SỐ


#include<bits/stdc++.h>

using namespace std;

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>

using namespace std;

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;

void back(long pos){

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;

23.BAI BONG DEN

#include<bits/stdc++.h>

using namespace std;

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;}

void back(long pos,long ops){

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;

You might also like