【六月】复习课

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

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

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

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]<<" ";
}
View Code

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

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

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

 

posted @ 2022-06-22 11:08  Oranges  阅读(29)  评论(0编辑  收藏  举报