zoukankan      html  css  js  c++  java
  • 0823模拟赛

    由于3道题都做对了,我就懒得写题解了。

    一、搭桥

    题目描述 Description

    有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物。现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建,如下图城市1有5栋建筑物,可以搭建4座桥将建筑物联系起来。城市2有两座建筑物,但不能搭建桥梁将它们连接。城市3只有一座建筑物,城市4有3座建筑物,可以搭建一座桥梁联系两栋建筑物,但不能与第三座建筑物联系在一起。

     

    输入描述 Input Description

    在输入的数据中的第一行包含描述城市的两个整数r 和c, 分别代表从北到南、从东到西的城市大小(1 <= r <= 50 and 1 <=  c <= 50). 接下来的r 行, 每一行由c 个(“#”)和(“.”)组成的字符. 每一个字符表示一个单元格。“#”表示建筑物,“.”表示空地。

    输出描述 Output Description

    在输出的数据中有两行,第一行表示建筑物的数目。第二行输出桥的数目和所有桥的总长度。

    样例输入 Sample Input

    样例1

    3 5

    #...#

    ..#..

    #...#

    样例2

    3 5

    ##...

    .....

    ....#

    样例3

    3 5

    #.###

    #.#.#

    ###.#

    样例4:

    3 5

    #.#..

    .....

    ....#

    样例输出 Sample Output

    样例1

    5

    4 4

    样例2

    2

    0 0

    样例3

    1

    0 0

    样例4

    3

    1 1

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<string>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define N 100010
    #define M 60
    #define ll long long
    #define xx first
    #define yy second
    typedef pair<int,int> diy;
    inline const int read(){
        register int x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline const bool in(){
        for(register char ch=getchar();;ch=getchar()) if(ch=='#'||ch=='.') return ch=='#';
    }
    const int dx[]={0,0,1,1,-1,-1,1,-1};
    const int dy[]={1,-1,1,-1,1,-1,0,0};
    bool mp[M][M];
    int fa[N],mark[M][M];
    int ans,sum,n,m,cnt;
    struct node{
        int x,y,v;
        bool operator < (const node &a) const{
            return v<a.v;
        }
    }e[N];
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void dfs(int x,int y){
        mark[x][y]=ans;
        for(int i=0,nx,ny;i<8;i++){
            nx=x+dx[i];
            ny=y+dy[i];
            if(mp[nx][ny]&&!mark[nx][ny]){
                dfs(nx,ny);
            }
        }
    }
    void work1(){
        ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(mp[i][j]&&!mark[i][j]){
                    ans++;
                    dfs(i,j);
                }
            }
        }
        printf("%d
    ",ans);
    }
    bool insert(int x1,int y1,int x2,int y2,int v){
        if(x2<1||x2>n||y2<1||y2>m||!mark[x2][y2]) return 1;
        if(mark[x1][y1]==mark[x2][y2]) return 0;
        e[++cnt].x=mark[x1][y1];
        e[cnt].y=mark[x2][y2];
        e[cnt].v=v-1;
        return 1;
    }
    void build(int x,int y){
        for(int i=x+1;i<=n;i++){
            if(!insert(x,y,i,y,i-x)||!insert(x,y,i,y+1,i-x)||!insert(x,y,i,y-1,i-x)){
                break;
            }
        }
        for(int i=x-1;i;i--){
            if(!insert(x,y,i,y,x-i)||!insert(x,y,i,y+1,x-i)||!insert(x,y,i,y-1,x-i)){
                break;
            }
        }
        for(int i=y+1;i<=m;i++){
            if(!insert(x,y,x,i,i-y)||!insert(x,y,x+1,i,i-y)||!insert(x,y,x-1,i,i-y)){
                break;
            }
        }
        for(int i=y-1;i;i--){
            if(!insert(x,y,x,i,y-i)||!insert(x,y,x+1,i,y-i)||!insert(x,y,x-1,i,y-i)){
                break;
            }
        }
    }
    void work2(){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(mp[i][j]){
                    build(i,j);
                }
            }
        }
        sort(e+1,e+cnt+1);
        for(int i=1;i<=ans;i++) fa[i]=i;
        ans=0;sum=0;
        for(int i=1,fx,fy;i<=cnt;i++){
            fx=find(e[i].x);
            fy=find(e[i].y);
            if(fx!=fy){
                fa[fy]=fx;
                ans++;
                sum+=e[i].v;
            }
        }
        printf("%d %d
    ",ans,sum);
    }
    
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                mp[i][j]=in();
            }
        }
        work1();
        work2();
        return 0;
    }

    二、产生数

    题目描述 Description

      给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15)。
      规则:
       一位数可变换成另一个一位数:
       规则的右部不能为零。
      例如:n=234。有规则(k=2):
        2-> 5
        3-> 6
      上面的整数 234 经过变换后可能产生出的整数为(包括原数):
       234
       534
       264
       564
      共 4 种不同的产生数
    问题:
      给出一个整数 n 和 k 个规则。
    求出:
      经过任意次的变换(0次或多次),能产生出多少个不同整数。
      仅要求输出个数。

    输入描述 Input Description

    键盘输人,格式为:
       n k
       x1 y1
       x2 y2
       ... ...
       xn yn

    输出描述 Output Description

     屏幕输出,格式为:
      一个整数(满足条件的个数)

    样例输入 Sample Input


       234 2
       2 5
       3 6

    样例输出 Sample Output

    4

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<string>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define N 10010
    #define M 60
    #define ll long long
    #define xx first
    #define yy second
    typedef pair<int,int> diy;
    inline const int read(){
        register int x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int num[M],a[M][M];
    char s[N];
    int f[N],p;
    void deal(int x){
        for(int j=1;j<=p;j++){
            f[j]*=x;
        }
        for(int j=1;j<=p<<1;j++){
            if(f[j]>9){
                f[j+1]+=f[j]/10;
                f[j]%=10;
            }
        }
        while(f[p+1]) p++;
    }
    int main(){
        //freopen("sh.txt","r",stdin);
        int i,j,k,x,y;
        scanf("%s %d",s,&k);
        while(k--) scanf("%d%d",&x,&y),a[x][y]=1;
        for(k=0;k<10;k++){
            for(i=0;i<=10;i++){
                for(j=0;j<10;j++){
                    if(i!=j&&i!=k&&j!=k){
                        if(a[i][k]&&a[k][j]){
                            a[i][j]=1;
                        }
                    }
                }
            }
        }
        for(i=0;i<10;i++){
            for(j=0;j<10;j++){
                num[i]+=a[i][j];
            }
        }    
        f[1]=1;p=1;
        //ll sum=1;
        //for(i=0;i<strlen(s);i++) sum*=(ll)(num[s[i]-'0']+1);
        //cout<<sum;
        for(i=0;i<strlen(s);i++) deal(num[s[i]-'0']+1);
        for(i=p;i;i--) printf("%d",f[i]);
        return 0;
    }

    三、装箱问题

    题目描述 Description

    有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。

    要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

    输入描述 Input Description

    一个整数v,表示箱子容量

    一个整数n,表示有n个物品

    接下来n个整数,分别表示这n 个物品的各自体积

    输出描述 Output Description

    一个整数,表示箱子剩余空间。

    样例输入 Sample Input

    24

    6

    8

    3

    12

    7

    9

    7

    样例输出 Sample Output

    0

    AC代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define N 100020
    int n,m,c[N],f[N];
    int main(){
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++) scanf("%d",&c[i]);
        for(int i=1;i<=n;i++){
            for(int j=m;j>=c[i];j--){
                f[j]=max(f[j],f[j-c[i]]+c[i]);
            }
        }
        printf("%d
    ",m-f[m]);
        return 0;
    }
  • 相关阅读:
    oracle 视图views
    5分钟把任意网站变成桌面软件
    Angular http跨域
    jQuery版本升级踩坑大全
    redis 模糊删除key
    jedisCluster 报错: redis.clients.jedis.exceptions.JedisClusterException: No way to dispatch this command to Redis Cluster because keys have different slots.
    mac电脑复制键失灵
    java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比
    linux光标操作
    redis hashmap数据结构分析
  • 原文地址:https://www.cnblogs.com/shenben/p/5798512.html
Copyright © 2011-2022 走看看