文件夹套文件夹,某些放入扑克牌,请你找出所有有扑克牌的文件夹,并说出你的方法。
请你写出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;
}