选拔赛总结

28 篇文章 0 订阅

问题 B: 消灭复读机

时间限制: 1 Sec  内存限制: 512 MB
提交: 18  解决: 9
[提交] [状态] [讨论版] [命题人:admin]

题目描述

手机端QQ推出了贴表情的新功能,复读机势力再次猖狂起来,她们把表情贴的到处都是!裙主决定把被复读次数最多的表情从聊天记录中删去。

聊天框是一个大小为n x m的黑白点阵。背景色是白色。我们定义“表情”是由黑色色块组成的极大四连通块。你的任务是找出聊天框中出现次数最多的表情,把这些表情都涂成白色,然后把处理好的聊天框输出出来。

保证表情的大小都小于32 x 32。

保证出现次数最多的表情只有一种。

 “极大四连通块”的定义为:从某一个黑色格子出发,向上下左右四个方向任意移动,且移动时不经过白色格子,通过这种移动方式能到达的所有黑色点称为一个“极大四连通块”。

 请参照样例理解题意。

输入

第一行两个整数n和m。 (1 =< n, m <= 1000)

接下来n行,每行一个长度为m的字符串。表示整个n x m的聊天框。

其中使用`.`来表示白色,使用`X`表示黑色。

输出

输出n行,每行一个长度为m的字符串。表示处理之后的聊天框。

样例输入

10 40
........................................
..X..X..X..X.....XXXXXX...X...X..X......
..X..X..X..X.....X........X...X..X......
..X..X..X..X.....X........X...X..X......
..X..X..X..X.....XXXXX....X...X..X......
..X..X..XXXXXX.......X....X...XXXXXX....
..X..X.....X.........X....X......X......
..X..X.....X.........X....X......X......
..X..X.....X.....XXXXX....X......X......
........................................

样例输出

........................................
........X..X.....XXXXXX.......X..X......
........X..X.....X............X..X......
........X..X.....X............X..X......
........X..X.....XXXXX........X..X......
........XXXXXX.......X........XXXXXX....
...........X.........X...........X......
...........X.........X...........X......
...........X.....XXXXX...........X......
........................................

思路:

dfs+map

超级神奇,每次dfs然后向上,右,下,左走分别对应的是字符'0','1','2','3',这样一次dfs下来就可以得到一个字符串,然后用map存字符串出现的次数。

并用map<string,vector<P> >ppp; 来存这个字符串对应的所有的起始位置,(P定义的是pair类型,存横纵坐标)

然后再dfs一次,消灭最多出现的表情就可以啦~

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
const int N=1010,mod=32767;
char mape[N][N],mape1[N][N];
string s;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int n,m;
map<string,int>qqq;
map<string,vector<P> >ppp;
void dfs(int x,int y){
    mape[x][y]='.';
    for(int i=0;i<4;i++){
        int nx=x+dx[i],ny=y+dy[i];
        if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mape[nx][ny]=='X'){
            dfs(nx,ny);
            char t=i+'0';
            s+=t;
        }
    }
}

void dfs1(int x,int y){
    mape1[x][y]='.';
    for(int i=0;i<4;i++){
        int nx=x+dx[i],ny=y+dy[i];
        if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mape1[nx][ny]=='X'){
            dfs1(nx,ny);
        }
    }
}

int main(){
    scanf("%d%d",&n,&m);
    getchar();
    char ch;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            ch=getchar();
            mape[i][j]=mape1[i][j]=ch;
        }
        getchar();
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(mape[i][j]=='X'){
                s="";
                P p;
                p.first=i;p.second=j;
                dfs(i,j);
                ppp[s].push_back(p);
                qqq[s]++;
            }
        }
    }
    int mx=0;
    string tmp;
    for(map<string,int>::iterator it=qqq.begin();it!=qqq.end();it++){
        if(mx<(it->second)){
            mx=it->second;
            tmp=it->first;
        }
    }
    for(int i=0;i<ppp[tmp].size();i++){
        P t=ppp[tmp][i];
        dfs1(t.first,t.second);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            printf("%c",mape1[i][j]);
        }
        printf("\n");
    }
}

 

4376: 上课点名

时间限制: 1 Sec  内存限制: 128 MB
提交: 235  解决: 17
[提交] [状态] [讨论版] [命题人:admin]

题目描述

在体育课上,同学们常常会迟到几分钟,但体育课J老师的点名却一直很准时。老师只关心同学的身高,他会依次询问当前最低的身高,次低的身高,第三低的身高,等等。也就是说,老师在第i次询问时,会问第i高的同学身高是多少。在询问的过程中,会不时地有人进入队伍中,每位同学进入后,老师可能不询问,也可能进行一个或多个询问。

现在让你回答老师每次的询问。

 

输入

第一行两个整数 n m,表示先后有 n 个人进队,老师询问了 m 次
第二行 n 个整数,第 i 个数 Ai 表示第 i 个进入队伍的同学的身高为 Ai
第三行 m 个整数,第 j 个数 Bj 表示老师在第 Bj 个同学进入队伍后有一次询问


1 =<n, m <= 30000,          0=<Ai<=2^32
 

 

输出

m 行,每行一个整数,依次表示老师每次询问的答案。数据保证合法

 

样例输入

7 4
9 7 2 8 14 1 8
1 2 6 6

 

样例输出

9
9
7
8

 

提示

样例解释:
第1个同学进入后进行第1次询问,当前队伍:(9)  询问结果:{第1低身高No.1 = 9};
第2个同学进入后进行第2次询问,当前队伍:(9 7)  询问结果: {第2低身高No.2 = 9};
第6个同学进入后进行第3次和第4次询问 ,当前队伍: (9 7 2 8 14 1)  询问结果:{第3低身高No.3 = 7} {第4低身高No.4 = 8}

思路:

一想到插入时有序,我就想用multiset,但是,set有个缺陷,它无法快速找到第i的元素,我们可以用vector实现这一功能,用vector插入时,每次先vector<int>::iterator it=lower_bound(a.begin(),a.end(),b[j])

然后a.insert(it,b[j]);

(好机智啊= =)

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<int,int>P;
const int INF=0x3f3f3f3f;
const int N=30010,mod=32767;
vector<ll>shengao;
ll a[N];

struct A{
    int seq,num;
    ll ans;
}b[N];
bool cmp(A a,A b){
    return a.num<b.num;
}
bool cmp1(A a,A b){
    return a.seq<b.seq;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    int t;
    for(int i=1;i<=m;i++){
        scanf("%d",&t);
        b[i].seq=i;
        b[i].num=t;
    }
    sort(b+1,b+1+m,cmp);
    int last=1,now;
    for(int i=1;i<=m;i++){
        now=b[i].num;
        for(int j=last;j<=now;j++){
            vector<ll>::iterator it=lower_bound(shengao.begin(),shengao.end(),a[j]);
            shengao.insert(it,a[j]);
        }
        b[i].ans=shengao[b[i].seq-1];
        last=now+1;
    }
    sort(b+1,b+1+m,cmp1);
    for(int i=1;i<=m;i++){
        printf("%lld\n",b[i].ans);
    }
}

总结:

emmm,怎么说呢,结果还是很开心的,得到了去天梯赛和省赛的名额,这可是我梦寐以求了一年的QwQ。

但是,我还是经验不足,这次比赛,本来4小时,老师又延长了1小时,我晕死,因为中午饭就吃的可少,最后一小时的时候就顶不住了,没劲+脑壳疼,我开始放弃治疗,喝奶茶ing,然后又让A题多wa了几次,就这么消磨时间……直到……

最后20分钟,我突然有了复读机那题的思路!!!

然后开始马上马立刻立的敲,DEV好难用,手速慢,呜呜呜,然后就没写完。

总之,stl运用不熟练,虽然有遗憾,但是,结果是好的qwq

以后也要加油呀~

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值