2022/1/25

题目1:迷宫问题

问题描述:设有一个N*N(2<=N<10)方格的迷宫,入口和出口分别在左上角和右上角。迷宫格子中分别放0和1,0表示可通,1表示不能,入口和出口处肯定是0。迷宫走的规则如下:

从某点开始,有八个方向可走,前进方格中数字为0时表示可通过,为1时表示不可通过,要另找路径。找出所有从入口到出口的路径(不能重复),输出路径总数,如果无法到达,则输出0。

想法:深搜,一个一个试,走过的地方变成1,不走回头路

输入样例:

3

0 0 0

0 1 1

1 0 0

输出样例:

2

程序:

#include<bits/stdc++.h>
using namespace std;
int N,Map[11][11],f[3]={-1,0,1};
int sum;
void MG(int x,int y){
    if(x<1||x>N||y<1||y>N){
        return;
    }
    if(x==1&&y==N){
        sum++;
        return;
    }
    else{
        Map[x][y]=1;
        for(int i=0;i<=2;i++){
            for(int j=0;j<=2;j++){
                if(Map[x+f[i]][y+f[j]]==0){
                    Map[x+f[i]][y+f[j]]=1;
                    MG(x+f[i],y+f[j]);
                    Map[x+f[i]][y+f[j]]=0;
                }
            }
        }
    }
}
int main(){
    scanf("%d",&N);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            scanf("%d",&Map[i][j]);
        }
    }
    MG(1,1);
    printf("%d",sum);
    return 0;
}

题目2:部落卫队

问题描述:原始部落byteland中的居民们为了争夺有限的资源,经常发生冲突。几乎每个居民都有他的仇敌。部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍,并保证队伍中任何2个人都不是仇敌。(选的人为1,不选的人为0)

思路:01背包,选了就不能选仇敌,不选再说

输入样例:

7 10

1 2

1 4

2 4

2 3

2 5

2 6

3 5

3 6

4 5

5 6

输出样例:

3

1 0 1 0 0 0 1

程序:

#include<bits/stdc++.h>
using namespace std;
int n,m,Di[101][101],direnshu[101]={0},A[101]={0},ans[101]={0},Max=-1,u,v;
int b[101]={0};
void XuanRen(int x,int z){
    if(x>n){
        if(z>Max){
            Max=z;
            for(int i=1;i<=n;i++){
                ans[i]=A[i];
            }
        }
    }
    else{
        if(b[x]==0){
            b[x]=1;A[x]=1;
            for(int j=1;j<=direnshu[x];j++){
                b[Di[x][j]]++;
            }
            XuanRen(x+1,z+1);
            b[x]--;A[x]=0;
            for(int i=1;i<=direnshu[x];i++){
                b[Di[x][i]]--;
            }
            XuanRen(x+1,z);
        }
        else{
            XuanRen(x+1,z);
        }
    }
    return;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        direnshu[u]++;
        Di[u][direnshu[u]]=v;
    }
    XuanRen(1,0);
    printf("%d\n",Max);
    for(int i=1;i<=n;i++){
        printf("%d ",ans[i]);
    }
    return 0;
}

题目3:最佳调度问题

问题描述:假设有n个任务由k个可并行工作的机器完成,完成任务i需要的时间为ti。找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。

输入样例:

7 3

2 14 4 16 6 5 3

输出样例:

17

程序:

#include<bits/stdc++.h>
using namespace std;
long long n,k,a[7001],z[7001],ans=10000000000;
inline void dfs(int x,long long zhi)
{
    if(x==n)
    {
        ans=min(ans,zhi);
        return;
    }
    if(zhi>=ans)
    return;
    for(int i=0;i<k;i++)
    {
        if(z[i]+a[x]<=ans){
        z[i]+=a[x];
        dfs(x+1,max(zhi,z[i]));
        z[i]-=a[x];
        }
    }
}
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    sort(a,a+n,cmp);
    dfs(0,0);
    cout<<ans;
}

题目4:图的m着色问题

问题描述:给定无向连通图G和m种不同的颜色,用这些颜色为图G的各个顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图的m着色问题是对于给定图G和m种颜色,找出所有不同的着色法。

输入样例:

5 8 4

1 2

1 3

1 4

2 3

2 4

2 5

3 4

4 5

输出样例:

48

程序:

#include <bits/stdc++.h>
using namespace std;
int n,m,ans=0,color;//n个点 ,m条边 ,color种颜色
bool b[110][110];
int vis[110];
bool check_(int x,int col){
    for(int i=1;i<x;i++){
        if(vis[i]==col&&(b[i][x]==true||b[x][i]==true)){
            return false;
        }
    }
    return true;
}
void dfs(int x){//正在选编号为x的点
    if(x>n){
        ans++;
        return;
    }
    for(int i=1;i<=color;i++){
        if(check_(x,i)){
            vis[x]=i;
            dfs(x+1);
            vis[x]=0;
        }
    }
}
int main(){
    memset(b,false,sizeof(b));
    scanf("%d%d%d",&n,&m,&color);
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        b[x][y]=true;
        b[y][x]=true;
    }
    dfs(1);
    printf("%d",ans);
    return 0;
}

posted @ 2022-01-25 15:57  LZMiiu  阅读(100)  评论(0编辑  收藏  举报