码迷,mamicode.com
首页 > 其他好文 > 详细

0823模拟赛

时间:2016-08-23 13:14:37      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

由于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\n",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\n",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\n",m-f[m]);
    return 0;
}

 

0823模拟赛

标签:

原文地址:http://www.cnblogs.com/shenben/p/5798512.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!