0125模拟赛总结

1,迷宫问题

问题描述

设有一个N*N(2<=N<10)方格的迷宫,入口和出口分别在左上角和右上角,迷宫格子中分别放0和1,0表示可通,1表示不能,入口和出口处肯定是0,迷宫走的规则如下所示,即从某点开始,有八个方向可走,前进方格中数字为0时表示可通过,为1时表示不可通过,要另找路径。找出所有从入口(左上角)到出口(右上角)的路径(不能重复),输出路径总数,如果无法到达,则输出0。

输入样例

3

0 0 0

0 1 1

1 0 0

输出样例

2  //路径总数

首先,出口在右上角不在右下角……

共八种走法可以用数组存储,注意要添加bool型数组判断,保证不重复。

#include<bits/stdc++.h>
using namespace std;
int n,a[12][12],ans;
int b[8][2]={{1,0},{1,1},{0,1},{0,-1},{-1,0},{-1,-1},{1,-1},{-1,1}};
bool c[12][12];
void search(int x,int y,int t){
    for(int i=0;i<8;i++){
        if(c[x+b[i][0]][y+b[i][1]]==0&&x+b[i][0]>=1&&x+b[i][0]<=n&&y+b[i][1]>=1&&y+b[i][1]<=n&&a[x+b[i][0]][y+b[i][1]]!=1){//判断是否重复,是否超过迷宫范围,是否有障碍
            x+=b[i][0];y+=b[i][1];c[x][y]=1;
            if(x==1&&y==n){ans++;}
            else search(x,y,t+1);
            c[x][y]=0;x-=b[i][0];y-=b[i][1];
        }
    }
}
int main(){
    c[1][1]=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&a[i][j]);
    search(1,1,1);
    printf("%d",ans);
    return 0;
}

2.部落卫队

题目描述

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

给定 byteland 部落中居民间的仇敌关系,编程计算组成部落卫队的最佳方案。若有多种方案可行,输出字典序最大的方案。

输入格式

1 行有 2 个正整数 n 和 m,表示 byteland 部落中有 n 个居民,居民间有 mmm 个仇敌关系。居民编号为1,2,……,n。接下来的m行中,每行有两个正整数u和v,表示居民u和v是仇敌。

输出格式

第一行是部落卫队的总人数,第二行是居民组成xi,i=0表示居民xi不在卫队中,i=1表示居民xi在卫队中。

输入样例

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

一定要开一个二维数组存储仇敌关系,否则tle,re等小可爱会接踵而至。

#include<bits/stdc++.h>
using namespace std;
int m,n,ans[110];
int ch[110][110];
int x[110],tot,maxx;
void search(int t){
    if(t>n){
        if(tot<=maxx) return;
        maxx=tot;
        for(int j=1;j<=n;j++) ans[j]=x[j];
        return;
    }
    bool tf=1;
    for(int i=1;i<t;i++){
        if(ch[i][t]==1&&x[i]==1){
            tf=0;break;
        }
    }
    if(tf==1){
        x[t]=1;tot++;
        search(t+1);
        tot--;x[t]=0;
    }
    search(t+1);
}
int main(){
    scanf("%d%d",&n,&m);
    int q,w;
    for(int i=1;i<=m;i++){
        cin>>q>>w;
        ch[q][w]=1;ch[w][q]=1;
    }
    search(1);
    cout<<maxx<<endl;
    for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
    return 0;
}

3.最佳调度问题

问题描述

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

编程任务

对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1~n。编程计算完成这n个任务的最佳调度。

输入样例

7  3

2  14  4  16  6  5  3

输出样例

17

研究表明,当算法过于复杂的时候快读和快写并没有什么用。

#include<bits/stdc++.h>
using namespace std;
int n,k,a[500],ans=10000,b[500];
int max(int q,int w){
    if(q>w) return q;
    else return w;
}
int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
void write(int x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
bool cmp(int x,int y){
    return x>y;
}
void search(int tot,int t){
    if(tot>n){
        if(t<ans) ans=t;
    }
    if(t>=ans) return;//剪枝
    for(int i=1;i<=k;i++){
        if(b[i]+a[tot]<ans){
            b[i]+=a[tot];
            search(tot+1,max(t,b[i]));
            b[i]-=a[tot];
        }
    }
}
int main(){
    //scanf("%d%d",&n,&k);
    n=read();k=read();
    for(int i=1;i<=n;i++){scanf("%d",&a[i]);}
    sort(a+1,a+n+1,cmp);//降低时间复杂度
    search(0,0);
    write(ans);
    return 0;
}

4.图的m着色问题

题目背景

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

题目描述

对于给定的无向连通图G和m种不同的颜色,编程计算图的所有不同的着色法。

输入格式

第1行有3个正整数n,k 和m,表示给定的图G有n个顶点和k条边,m种颜色。顶点编号为1,2,…,n。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。

输出格式

程序运行结束时,将计算出的不同的着色方案数输出。

经验教训同第二题。。。

#include<bits/stdc++.h>
using namespace std;
int n,k,m,b[1001],ans;
bool c[1001][1001];
bool pd(int t,int se){
    for(int i=1;i<t;i++){//终止条件一定是到t
        if(c[t][i]==1&&se==b[i]) return 0;
    }
    return 1;
}
void search(int t){
    if(t>n){ans++;return;}
    for(int i=1;i<=m;i++){
        if(pd(t,i)){
            b[t]=i;
            search(t+1);
            b[t]=0;
        }
    }
}
int main(){
    int q,w;
    scanf("%d%d%d",&n,&k,&m);
    for(int i=1;i<=k;i++){
        scanf("%d%d",&q,&w);
        c[q][w]=1;c[w][q]=1;
    }
    search(1);
    printf("%d",ans);
    return 0;
}

posted @   专吃小仙女  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示