Jeanny
寂兮,寥兮,独立不改,周行而不殆

文件夹套文件夹,某些放入扑克牌,请你找出所有有扑克牌的文件夹,并说出你的方法。

请你写出4个数的全排列

for(int i = 1; i <= 4; i++)
      for
            for
                  for
方法: 递进深度,枚举可行值

P1157 组合的输出

#include<bits/stdc++.h>
using namespace std;
int n,r,a[25];
void dfs(int t){
	if(t==r+1){
		for(int i=1;i<=r;i++)
			printf("%3d",a[i]);
		printf("\n");
		return ;
	}
	for(int i=a[t-1]+1;i<=n;i++){
		a[t]=i;
		dfs(t+1);	
	}
}
int main(){
	scanf("%d%d",&n,&r);
	dfs(1);
}

3.P1036 选数

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[25],ans,n,k,b[25],c[25],sum;
bool chk(int x){
  for(int i=2;i<=sqrt(x);i++){
    if(x%i==0) return 0;
  }
  return 1;
}
void dfs(int t){
  if(t==k+1){
    if(chk(sum)) ans++;
    return ;
  }
  for(int i=c[t-1]+1;i<=n;i++){
      c[t]=i;//存位置
      sum+=a[i];
      dfs(t+1);
      sum-=a[i];
  }
}
int main(){
  scanf("%d%d",&n,&k);
  for(int i=1;i<=n;i++){
    scanf("%d",&a[i]);
  }
  dfs(1);
  printf("%d\n",ans);
}

4.T113146素数环

#include<iostream>
#include<cstdio>
#include<cmath> 
#include<cstring>
using namespace std;
int n,a[20]={0,1},b[20];
bool chk(int x){
	for(int i=2;i<=sqrt(x);i++){
		if(x%i==0)return 0;
	}
	return 1;
}
void dfs(int t){
	if(t==n+1){
		if(chk(1+a[n])){
			for(int i=1;i<=n-1;i++)
				printf("%d ",a[i]);
			printf("%d\n",a[n]);
		}
		return;
	}
	for(int i=2;i<=n;i++){
		if(!b[i]&& chk(a[t-1]+i)){
			b[i]=1;
			a[t]=i;
			dfs(t+1);
			b[i]=0;
		}
	}
}
int ca=0;
int main()
{
	while(scanf("%d",&n)!=EOF){
		if(ca!=0) printf("\n");
		ca++;
		printf("Case %d:\n",ca);
		dfs(2);	
		memset(b,0,sizeof b);///////////
//		printf("\n");
	} 
}

P2089 烤鸡

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int sum = 0, n, a[15], cnt, b[100005][15];
void dfs(int t){
  if(sum + (n-t)*1 > n) return;//可行性剪枝
  if(sum + (n-t)*9 < n) return;//可行性剪枝
  if(t == 11){
    if(sum == n){
      cnt++;
      for(int i = 1; i <= 10; i++)
        b[cnt][i] = a[i];
    }
    return;
  }
  for(int i = 1; i <= 3; i++){
    a[t] = i;
    sum += i;
    dfs(t + 1);
    sum -= i;
  }
}
int main(){
  scanf("%d",&n);
  dfs(1);
  printf("%d\n",cnt);
  for(int i = 1; i <= cnt; i++){
    for(int j = 1; j <= 10; j++)
      printf("%d ",b[i][j]);
    printf("\n");
  }

  return 0;
}

P1135 奇怪的电梯

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,s,t,mn=0x3fffffff,a[205],vis[205];
void dfs(int i,int sum)
{
	if(sum>mn) return;
	if(i==t && sum<mn) mn=sum;
	vis[i]=1;
	if(i+a[i]<=n && !vis[i+a[i]]) dfs(i+a[i],sum+1);
	if(i-a[i]>=1 && !vis[i-a[i]]) dfs(i-a[i],sum+1);
	vis[i]=0;
}
int main()
{
	scanf("%d%d%d",&n,&s,&t);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	dfs(s,0);
	if(mn<0x3fffffff)
		printf("%d\n",mn);
	else
		printf("-1\n");
}

P1219 [USACO1.5]八皇后 Checker Challenge

#include<bits/stdc++.h>
using namespace std;
int n,a[15],b[15],l[105],r[105],cnt;
void dfs(int t){
	if(t==n+1){
		cnt++;
		if(cnt>3) return ;
		for(int i=1;i<=n;i++)
			printf("%d ",a[i]);
		printf("\n");
		return ;
	} 
	for(int i=1;i<=n;i++){
		if(!b[i] && !l[t+i] && !r[t-i+n]){
			b[i]=1;
			l[t+i]=1;
			r[t-i+n]=1;
			a[t]=i;//用来存第几行第几列 
			dfs(t+1);
			b[i]=0;
			l[t+i]=0;
			r[t-i+n]=0;
		}
	}
}
int main(){
	scanf("%d",&n);
	dfs(1);
	cout<<cnt<<endl;
}

P1236 算24点

要怎样记录这个过程呢?可以想到主函数选择一个数,dfs依次枚举可以选择的数字,将ans和当前数字进行运算。
但是会有两个两个运算的情况 (x,y)(a,b)
因为计算24点的过程总是先取出其中两个数进行加减乘除的运算,
再将结果放入进行下一轮的运算,这样的话在dfs中枚举两个数字,因此就是两个for循环
出口条件即为只剩下一个数时,判断该数是否为24,若为24,则返回true,否则返回false。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define eps 1e-4
using namespace std;
int p[5][5];
char str[5];
int a[5];
int fl,vis[5];
void dfs(int t){
	if(t==3){
		for(int i=1;i<=4;i++){
			if(!vis[i] && a[i] == 24){
				fl=1;
				break;
			}
		}
		if(fl == 1){
			for(int i = 0; i < t; i++){
				printf("%d%c%d=%d\n",p[i][1],str[i],p[i][2],p[i][3]);
			}
			exit(0);
		}
		return;
	}
	for(int i=1;i<=4;i++){
		if(!vis[i])
		for(int j=1;j<=4;j++){
			if(i == j) continue;
			if(!vis[j]){
				if(a[i] < a[j])continue;
				vis[j]=1;
				int tma,tmb;tma=a[i],tmb=a[j];//写成int

				a[i]=tma+tmb;
        		p[t][1] = tma;p[t][2] = tmb;p[t][3] = tma +tmb;str[t] = '+';
				dfs(t+1);

				a[i]=tma-tmb;
				p[t][1] = tma;p[t][2] = tmb;p[t][3] = tma -tmb;str[t] = '-';
				dfs(t+1);

				a[i]=tma*tmb;
				p[t][1] = tma;p[t][2] = tmb;p[t][3] = tma *tmb;str[t] = '*';
				
				dfs(t+1);


				if(tmb!=0 && tma%tmb == 0){
					a[i]=tma/tmb;
					p[t][1] = tma;p[t][2] = tmb;p[t][3] = tma /tmb;str[t] = '/';///////
					dfs(t+1);
				}


				a[i]=tma;vis[j]=0;
			}
		}
	}

}
int main(){
	scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]);
	memset(vis,0,sizeof vis);fl=0;
	dfs(0);
	printf("No answer!\n");
	return 0;
}

P1135 奇怪的电梯

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,s,t,mn=0x3fffffff,a[205],vis[205];
void dfs(int i,int sum)
{
	if(sum>mn) return;
	if(i==t && sum<mn) mn=sum;
	if(i+a[i]<=n && !vis[i+a[i]]) vis[i+a[i]] = 1, dfs(i+a[i],sum+1), vis[i+a[i]] = 0;
	if(i-a[i]>=1 && !vis[i-a[i]]) vis[i-a[i]] = 1, dfs(i-a[i],sum+1), vis[i-a[i]] = 0;
}
int main()
{
	scanf("%d%d%d",&n,&s,&t);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	dfs(s,0);
	if(mn<0x3fffffff)
		printf("%d\n",mn);
	else
		printf("-1\n");
}

二维

P1605 迷宫

走过的还可以走,要么走过的路是可以到达终点的,因此回溯回去,其他的路还可以走刚才可以到达终点的。要么走过的路无法到达终点,则回溯回去,其他路再次走到这条路时,还是死路。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,t,cnt,fx,fy,vis[10][10],sx,sy,p,q,a[10][10];
int movx[5]={1,0,-1,0};
int movy[5]={0,1,0,-1};
void dfs(int x,int y){
	if(x==fx && y==fy) {
		cnt++;return; 
	}
	int xx,yy;
	for(int i=0;i<=3;i++){
		xx=x+movx[i];
		yy=y+movy[i];
		if(a[xx][yy]==0 && vis[xx][yy]==0 && xx<=n && xx>=1 && yy>=1 && yy<=n){
			vis[xx][yy]=1;
			dfs(xx,yy);
			vis[xx][yy]=0;
		}
	}
} 
int main()
{
	scanf("%d%d%d",&n,&m,&t);
	scanf("%d%d%d%d",&sx,&sy,&fx,&fy);
	vis[sx][sy]=1;
	for(int i=1;i<=t;i++){
		scanf("%d%d",&p,&q);
		a[p][q]=1;
	}
	dfs(sx,sy);
	printf("%d\n",cnt);		
}

P1644 跳马问题

#include<iostream>
#include<cstdio>
using namespace std;
int xt[105],yt[105],n,m,b[105][105],lx[10005],ly[10005];
int x[4]={2,1,-1,-2};
int y[4]={1,2,2,1};
int cnt;
void dfs(int sx,int sy,int t)
{
    if (sx==n && sy==m){
      // for(int i = 1; i <= t - 2; i++)
      //   cout<<lx[i]<<","<<ly[i]<<"->";
      // cout<<sx<<","<<sy<<endl;
      cnt++;return;
    }
	for(int j=0;j<=3;j++)
	{
		int xx=sx+x[j];
		int yy=sy+y[j];
    if (xx>=0 && xx<=n && yy>=0 && yy<=m){
      if(!b[xx][yy]){
        lx[t] = xx;
        ly[t] = yy;
        b[xx][yy] = 1;
        dfs(xx,yy,t+1);
        b[xx][yy] = 0;//加上所有路线,不加一种路线
      }
    }
	}
}
int main()
{
	scanf("%d%d",&n,&m);
  // cout<<"0,0"<<"->";
	dfs(0,0,1);
	printf("%d",cnt);
}

P1451 求细胞数量

P1657 选书


P1784 数独

#include<iostream>
#include<cstdio>
using namespace std;
int row[10][10],col[10][10],g[10][10];
int block[10][10]=
{
    { 0,0,0,0, 0,0,0, 0,0,0 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
};
int a[10][10];
int flag;
void print()
{
    for(int i=1;i<=9;i++)
    {
        for(int j=1;j<=9;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
}
void work(int x,int y)
{
    if(x==9 && y==10) {flag=1;print();return;}
    else if(y==10) x++,y=1;

    if(a[x][y]) work(x,y+1);
    else{
        for(int i=1;i<=9;i++)
        {
            if(row[x][i]==0 && col[y][i]==0 && g[block[x][y]][i]==0)//判断数字i合不合适
            {
                row[x][i]=1;
                col[y][i]=1;
                g[block[x][y]][i]=1;
                a[x][y]=i;
                work(x,y+1);
                row[x][i]=0;
                col[y][i]=0;
                g[block[x][y]][i]=0;
                a[x][y]=0;
            }
            if(flag==1) return;
        }
    }
}
int main()
{
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
        {
            scanf("%d",&a[i][j]);
            row[i][a[i][j]]=1;
            col[j][a[i][j]]=1;
            g[block[i][j]][a[i][j]]=1;
        }
    work(1,1);
}

P1074 靶形数独

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int x,t=81,flag;
int a[15][15],row[15][15],col[15][15],block[15][15],nxt[15],mx,fl;
int ju[10][10]={
0,0,0,0,0,0,0,0,0,0,
0,1,1,1,2,2,2,3,3,3,
0,1,1,1,2,2,2,3,3,3,
0,1,1,1,2,2,2,3,3,3,
0,4,4,4,5,5,5,6,6,6,
0,4,4,4,5,5,5,6,6,6,
0,4,4,4,5,5,5,6,6,6,
0,7,7,7,8,8,8,9,9,9,
0,7,7,7,8,8,8,9,9,9,
0,7,7,7,8,8,8,9,9,9,
};
int v[10][10]=
{
0,0,0,0,0, 0,0,0,0,0,
0,6,6,6,6, 6,6,6,6,6,
0,6,7,7,7, 7,7,7,7,6,
0,6,7,8,8, 8,8,8,7,6,
0,6,7,8,9, 9,9,8,7,6,
0,6,7,8,9,10,9,8,7,6,
0,6,7,8,9, 9,9,8,7,6,
0,6,7,8,8, 8,8,8,7,6,
0,6,7,7,7, 7,7,7,7,6,
0,6,6,6,6, 6,6,6,6,6
};
struct Node{
  int cnt,id;
}hang[15];
bool cmp(Node x, Node y){
  return x.cnt > y.cnt;
}
void dfs(int rm, int tx, int ty, int sum) {
    if(sum + rm * 90 < mx) return;
    if(rm==0) {
      // for(int i = 1; i <= 9; i++){
      //   for(int j = 1; j <= 9; j++)
      //     printf("%d ",a[i][j]);
      //   printf("\n");
      // }
      fl = 1;
      if(sum > mx) mx = sum;
      return;
    }
    if(ty == 10) tx = nxt[tx], ty=1;
    // if(ty == 10) dfs(rm, nxt[tx], ty);
    if(a[tx][ty]) dfs(rm,tx,ty+1,sum + v[tx][ty]*a[tx][ty]);
    else{
      int tc=ju[tx][ty];
      for(int i=1;i<=9;i++) //先放置可选择数目最少的空位,如果在上面可以记录可以放那些数更好
  		if(!row[tx][i] && !col[ty][i] && !block[tc][i]){
        // cout<<tx<<" "<<ty<<" "<<i<<endl;
             a[tx][ty]=i;
             row[tx][i]=1;
             col[ty][i]=1;
      	     block[tc][i]=1;
             dfs(rm-1, tx, ty+1,sum + i*v[tx][ty]);
             row[tx][i]=0;
      		   col[ty][i]=0;
      		   block[tc][i]=0;
             a[tx][ty]=0;
     		}
    }
}
int main()
{
    for(int i=1;i<=9;i++){
      int num = 0;
      hang[i].id = i;
      for(int j=1;j<=9;j++) {
          scanf("%d",&a[i][j]);
          if(a[i][j]>0) {
            row[i][a[i][j]]=1;
            col[j][a[i][j]]=1;
            block[ju[i][j]][a[i][j]]=1;
            t--;
            num++;
          }
      }
      hang[i].cnt = num;
    }
    sort(hang + 1, hang + 10, cmp);
    for(int i = 1; i <= 8; i++){
      nxt[hang[i].id] = hang[i+1].id;
      // cout<<hang[i].id<<endl;
      // cout<<hang[i].id<<" "<<hang[i+1].id<<endl;
    }
    dfs(t, hang[1].id, 1,0);
    if(fl) cout<<mx<<endl;
    else cout<<-1<<endl;
    return 0;
}

P4573 [CQOI2013]新数独

输入:b[i][j][p][q]表示第i行第j列的数字和第p行第q列的数字大小关系

    for(int i = 1; i <= 9; i++) {
            int di = i+1;
            char ch;
            cin>>ch; b[i][1][i][2] = (ch=='>'?1:2);
            cin>>ch; b[i][2][i][3] = (ch=='>'?1:2);
            cin>>ch; b[i][4][i][5] = (ch=='>'?1:2);
            cin>>ch; b[i][5][i][6] = (ch=='>'?1:2);
            cin>>ch; b[i][7][i][8] = (ch=='>'?1:2);
            cin>>ch; b[i][8][i][9] = (ch=='>'?1:2);
            if(i % 3 == 0) continue;

            cin>>ch; b[i][1][di][1] = (ch=='v'?1:2);
            cin>>ch; b[i][2][di][2] = (ch=='v'?1:2);
            cin>>ch; b[i][3][di][3] = (ch=='v'?1:2);
            cin>>ch; b[i][4][di][4] = (ch=='v'?1:2);
            cin>>ch; b[i][5][di][5] = (ch=='v'?1:2);
            cin>>ch; b[i][6][di][6] = (ch=='v'?1:2);
            cin>>ch; b[i][7][di][7] = (ch=='v'?1:2);
            cin>>ch; b[i][8][di][8] = (ch=='v'?1:2);
            cin>>ch; b[i][9][di][9] = (ch=='v'?1:2);

优化输入书写方式:

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
int row[10][10],col[10][10],g[10][10],b[10][10][10][10];
int block[10][10]=
{
    { 0,0,0,0, 0,0,0, 0,0,0 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,1,1,1, 2,2,2, 3,3,3 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,4,4,4, 5,5,5, 6,6,6 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
    { 0,7,7,7, 8,8,8, 9,9,9 },
};
int a[10][10];
int flag;
void print(){
    for(int i=1;i<=8;i++){
        for(int j=1;j<=9;j++)
            printf("%d ",a[i][j]);
        printf("\n");
    }
    for(int j=1;j<=9;j++)
        printf("%d ",a[9][j]);
}
int tot = 0;
void work(int x,int y){
    if(x==9 && y==10) {flag=1;print();exit(0);}
    else if(y==10) x++,y=1;
    tot++;
    if(a[x][y]) work(x,y+1);
    else{
        for(int i=1;i<=9;i++){
            if(row[x][i]==0 && col[y][i]==0 && g[block[x][y]][i]==0){
                if(x-1 >= 1){
                    if(b[x-1][y][x][y] == 1){
                        if(i >= a[x-1][y]) continue;
                    }
                    else if(b[x-1][y][x][y] == 2)
                        if(i <= a[x-1][y]) continue;
                }
                if(y-1 >= 1){
                    if(b[x][y-1][x][y] == 1){
                        if(i >= a[x][y-1]) continue;
                    }
                    else if(b[x][y-1][x][y] == 2)
                        if(i <= a[x][y-1]) continue;
                }

                row[x][i]=1;
                col[y][i]=1;
                g[block[x][y]][i]=1;
                a[x][y]=i;
                work(x,y+1);
                row[x][i]=0;
                col[y][i]=0;
                g[block[x][y]][i]=0;
                a[x][y]=0;
            }
            if(flag==1) return;
        }
    }
}
int main(){
    for(int i = 1; i <= 9; i++) {
        int di = i+1; char ch;
        for(int j = 1; j <= 8; j++){
            if(j%3 == 0) continue;
            cin>>ch; b[i][j][i][j+1] = (ch == '>'? 1:2);
        }
        if(i % 3 == 0) continue;
        for(int j = 1; j<=9; j++){
            cin>>ch;
            b[i][j][di][j] = (ch=='v'?1:2);
        }
    }
    work(1,1);
}

P1092 虫食算

#include<bits/stdc++.h>
using namespace std;
int n,used[30],alp[5][30],num[5][30],data[30],vis[30];
//used 某数字是否被使用  alp 某位置上的字母  num 某位置上的数字  data 字母所对应的数字  vis 是否访问过某个字母 
char c[30];
void dfs(int row,int col,int pl){
	if(col==0){
	    for(int i=1;i<=n;i++)
	    {
			printf("%d ",data[i]); 
		}
		exit(0);
	}	
	for(int l=col;l>0;l--)
	{
		if(vis[alp[1][l]] && vis[alp[2][l]] && vis[alp[3][l]])
		{
			if((data[alp[1][l]]+data[alp[2][l]])%n !=data[alp[3][l]] && (data[alp[1][l]]+data[alp[2][l]]+1)%n !=data[alp[3][l]])
				return;
		}
	}
	if(vis[alp[row][col]]){
		num[row][col]=data[alp[row][col]];
		if(row==3){
			if((num[1][col]+num[2][col]+pl)%n==num[3][col])
				dfs(1,col-1,(num[1][col]+num[2][col]+pl)/n);
			else
				return;
		}
		else dfs(row+1,col,pl);
	}
	else{
		for(int i=0;i<n;i++){
			if(!used[i])
			{
				used[i]=1;
				data[alp[row][col]]=i;
				num[row][col]=i;
				vis[alp[row][col]]=1;
				if(row!=3){
						dfs(row+1,col,pl);		
				}
				else{
					if((num[1][col]+num[2][col]+pl)%n==i)
						dfs(1,col-1,(num[1][col]+num[2][col]+pl)/n);
				}
				used[i]=0;
				vis[alp[row][col]]=0;
			}	
		}
	}
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=3;i++){
			scanf("%s",c+1);
			for(int j=1;j<=n;j++)
				alp[i][j]=c[j]-'A'+1;
	}	
	memset(vis,0,sizeof vis);
	dfs(1,n,0);	
	return 0;
}
posted on 2020-09-25 20:37  Jeanny  阅读(118)  评论(0)    收藏  举报