【六月】复习课
p1219
#include <stdio.h> #include <string.h> #include <stdlib.h> int n; int a[100]; int visited[3][100]; int count=0; void dfs(int step){ int i,j; if(step==n+1){ count++; if(count<=3){ for(i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); } return; } for(i=1;i<=n;i++){ if(!visited[0][i]&&!visited[1][i+step]&&!visited[2][step-i+n]){ visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=1; a[step]=i; dfs(step+1); visited[0][i]=visited[1][i+step]=visited[2][step-i+n]=0; } } } int main(){ memset(visited,0,sizeof(visited)); scanf("%d",&n); dfs(1); printf("%d\n",count); return 0; }
p1605
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; int barrier[10][10]; int walkx[5] = {0,0,0,1,-1}; //x方向可以走的选择 int walky[5] = {0,-1,1,0,0}; //y方向可以走的选择 int n,m,t,sx,sy,fx,fy; //n行,m列,t障碍数,sx,sy起点坐标,fx,fy终点坐标 int result = 0; int flag[10][10]; void dfs(int x, int y){ if(x == fx && y == fy){ result++; return; //返回 } else{ for(int i = 1; i <= 4; ++i){ //上下左右四个方向可以走 if(flag[x+walkx[i]][y+walky[i]] == 0 && barrier[x+walkx[i]][y+walky[i]] == 1){ //是否已走过 && 是否有障碍 flag[x][y] = 1; //原先的标记为已走过 dfs(x+walkx[i],y+walky[i]); flag[x][y] = 0; //回溯 } } } } int main(){ scanf("%d%d%d",&n,&m,&t); scanf("%d%d%d%d",&sx,&sy,&fx,&fy); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= m; ++j){ barrier[i][j] = 1; //初始化为地图都不为障碍,即都可以走 } } int barrierx,barriery; for(int i = 1; i<= t; ++i){ scanf("%d%d",&barrierx,&barriery); barrier[barrierx][barriery] = 0; //更新障碍处 } dfs(sx,sy); //从起点开始深搜 printf("%d\n",result); return 0; }
p1451
#include<stdio.h> #include<algorithm> using namespace std; int n,m; int cell[105][105]; int vis[105][105]; int dx[4] = {0,0,1,-1}; int dy[4] = {1,-1,0,0}; int ans; void dfs(int x,int y){ vis[x][y]=1; for(int i=0;i<4;i++){ int nx=x+dx[i]; int ny=y+dy[i]; if(cell[nx][ny]&&vis[nx][ny]==0) dfs(nx,ny); } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%1d",&cell[i][j]); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(!vis[i][j]&&cell[i][j]) { dfs(i,j); ans++; } } } printf("%d",ans); return 0; }
p1177
#include<iostream> using namespace std; int n,a[1000001]; void qsort(int l,int r)//应用二分思想 { int mid=a[(l+r)/2];//中间数 int i=l,j=r; do{ while(a[i]<mid) i++;//查找左半部分比中间数大的数 while(a[j]>mid) j--;//查找右半部分比中间数小的数 if(i<=j)//如果有一组不满足排序条件(左小右大)的数 { swap(a[i],a[j]);//交换 i++; j--; } }while(i<=j);//这里注意要有= if(l<j) qsort(l,j);//递归搜索左半部分 if(i<r) qsort(i,r);//递归搜索右半部分 } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; qsort(1,n); for(int i=1;i<=n;i++) cout<<a[i]<<" "; }
p1228
#include <iostream> #include <cmath> using namespace std; // 正方形左上角坐标xx和yy,公主坐标x和y,正方形边长k void partition(int xx,int yy,int x,int y,int k){ if(k == 1) return; k/=2; // 左上角 if(x < xx+k && y < yy+k){ printf("%d %d %d\n",xx+k,yy+k,1); // 递归覆盖左上角 partition(xx,yy,x,y,k); // 覆盖右下角 partition(xx+k,yy+k,xx+k,yy+k,k); // 覆盖左下角 partition(xx+k,yy,xx+k,yy+k-1,k); // 覆盖右上角 partition(xx,yy+k,xx+k-1,yy+k,k); } // 右上角 else if(x < xx+k && y >= yy+k){ printf("%d %d %d\n",xx+k,yy+k-1,2); // 递归覆盖左上角 partition(xx,yy,xx+k-1,yy+k-1,k); // 覆盖右下角 partition(xx+k,yy+k,xx+k,yy+k,k); // 覆盖左下角 partition(xx+k,yy,xx+k,yy+k-1,k); // 覆盖右上角 partition(xx,yy+k,x,y,k); } // 左下角 else if(x >= xx+k && y < yy+k){ printf("%d %d %d\n",xx+k-1,yy+k,3); // 递归覆盖左上角 partition(xx,yy,xx+k-1,yy+k-1,k); // 覆盖右下角 partition(xx+k,yy+k,xx+k,yy+k,k); // 覆盖左下角 partition(xx+k,yy,x,y,k); // 覆盖右上角 partition(xx,yy+k,xx+k-1,yy+k,k); } // 右下角 else{ printf("%d %d %d\n",xx+k-1,yy+k-1,4); // 递归覆盖左上角 partition(xx,yy,xx+k-1,yy+k-1,k); // 覆盖右下角 partition(xx+k,yy+k,x,y,k); // 覆盖左下角 partition(xx+k,yy,xx+k,yy+k-1,k); // 覆盖右上角 partition(xx,yy+k,xx+k-1,yy+k,k); } } int main() { int x,y,k; cin >> k >> x >> y; partition(1,1,x,y,(1 << k)); return 0; }
p1439
#include<iostream> #include<cstdio> using namespace std; int a[100001],b[100001],map[100001],f[100001]; int main() { int n; cin>>n; for(int i=1;i<=n;i++){scanf("%d",&a[i]);map[a[i]]=i;} for(int i=1;i<=n;i++){scanf("%d",&b[i]);f[i]=0x7fffffff;} int len=0; f[0]=0; for(int i=1;i<=n;i++) { int l=0,r=len,mid; if(map[b[i]]>f[len])f[++len]=map[b[i]]; else { while(l<r) { mid=(l+r)/2; if(f[mid]>map[b[i]])r=mid; else l=mid+1; } f[l]=min(map[b[i]],f[l]); } } cout<<len; return 0; }
p1775
#include<stdio.h> #include<algorithm> using namespace std; int n; int m[305]; int dp[305][305];//dp[i][j]代表以i为起点,j为终点的区间的最优解 int sum[305];//sum[i]代表前i个堆的价值的总和 int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&m[i]); sum[i]=sum[i-1]+m[i]; //前缀和 } for(int len=2;len<=n;len++){ //枚举区间的长度 for(int i=1;i+len-1<=n;i++){ //枚举区间起点 int j=i+len-1; //计算区间的终点 dp[i][j] = 0x3f3f3f3f; //由于是求最小代价,因此为最优解初始化一个极大值 for(int k=i;k<j;k++){ //枚举区间分割点,以k为界将区间分割为左边的堆和右边的堆 int temp = dp[i][k]+dp[k+1][j]+(sum[j]-sum[i-1]); //sum[j]-sum[i-1] 代表 从i到j 的堆的价值总和 if(temp < dp[i][j]) dp[i][j]=temp; } } } printf("%d",dp[1][n]); return 0; }