0
点赞
收藏
分享

微信扫一扫

蓝桥杯真题练习【第九届】【省赛】【B组】

捡历史的小木板 2022-01-27 阅读 42

全球变暖

  1. b f s bfs bfs 求出所有的连通块,并且对每个连通块进行编号,因为数据到 1000 1000 1000,因此连通块至多 1 e 6 1e6 1e6块。
  2. 将所有会被淹没的陆地都变成海洋。
  3. 计算剩余的块数,只要看原来的连通块的编号是否还存在没有被淹没的陆地就好。
  4. 将原来的块数减去剩余的块数即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int num[1000][1000];
int n,cnt;
bool vis[N];
char g[1000][1000];
bool change[1000][1000];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
struct Node{ int x,y;};
void bfs(int x,int y){
    queue<Node>q;
    q.push({x,y});
    num[x][y]=cnt;
    while(!q.empty()){
        Node cur=q.front();q.pop();
        for(int i=0;i<4;i++){
            int nx=cur.x+dx[i],ny=cur.y+dy[i];
            if(nx<0||ny<0||nx>=n||ny>=n)continue;
            if(g[nx][ny]=='.'||num[nx][ny])continue;
            q.push({nx,ny});
            num[nx][ny]=cnt;
        }
    }
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>g[i][j];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(g[i][j]=='#'&&!num[i][j]){
                cnt++;
                bfs(i,j);
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(g[i][j]=='#'){
            for(int k=0;k<4;k++){
                int nx=i+dx[k],ny=j+dy[k];
                if(nx<0||ny<0||nx>=n||ny>=n||g[nx][ny]=='#')continue;
                change[i][j]=true;break;
            }
            }
        }
    }
    int ori_cnt=cnt;cnt=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(g[i][j]=='#'&&!change[i][j])vis[num[i][j]]=1;
        }
    }
    for(int i=1;i<=ori_cnt;i++){
        if(vis[i])cnt++;
    }
    cout<<ori_cnt-cnt<<endl;
    return 0;
}

乘积最大
选择问题考虑贪心,按绝对值从大到小排序,而且看题目是要我们求最大值之后再去取模,所以我们一定是把数选好了之后,将选好的数直接相乘然后取模的,无法边算边选。

因为有负数和选定个数的限制,因此应该是奇偶性的问题。

1. 若k==n,直接操作
2. 看前k个数(因为k!=n,若存在0,0必在第n个位置,因此前k个均不含0了,但是可能有很多个0呀)
	(1)若有偶数个负数:直接操作
	(2)若有奇数个负数:
		①. 若后n-k个有正数,取后n-k个的第一个正数而删除前k个的最后一个负数
		②. 若后n-k个有负数,前k个有正数,取后n-k个的第一个负数,删除前k个的最后一个正数
		③. 否则结果必为非正数,直接选后k个相乘

第一次提交发现ans乘正数和负数的取模方式是不一样的,就wa了,第二次发现ans1,ans2没有初始化,顺便发现ans1,ans2的位置写反了…得意的小技巧是:在判断大小的时候避免了浮点数计算,即判断①,②不同取法大小的时候用十字相乘法比较(好吧挺幼稚的)。
代码有点长,如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1E5+10;
const int mod=1000000009;
int n,k;
ll a[N];
ll mul(ll x,ll y){
    if(y<0)return (0-((0-x*y) % mod));
    else return x*y%mod;
}
bool cmp(ll x,ll y){
    return abs(x)>abs(y);
}
int main(){
    cin>>n>>k;
    int pos=0,neg=0,k_pos=0,k_neg=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]>0)pos++;
        if(a[i]<0)neg++;
    }
    sort(a+1,a+1+n,cmp);
    if(k==n){
        ll ans=1;
        for(int i=1;i<=k;i++)ans=mul(ans,a[i]);
        cout<<ans<<endl;
    }
    else {
        ll last_neg=0,last_pos=0,fir_neg=0,fir_pos=0;
        for(int i=1;i<=k;i++){
            if(a[i]>0){
                k_pos++;
                last_pos=a[i];
            }
            else if(a[i]<0){
                k_neg++;
                last_neg=a[i];
            }
        }
        for(int i=k+1;i<=n;i++){
            if(fir_neg==0&&a[i]<0)fir_neg=a[i];
            if(fir_pos==0&&a[i]>0)fir_pos=a[i];
        }
        if(k_neg%2==0){
            ll ans=1;
            for(int i=1;i<=k;i++)ans=mul(ans,a[i]);
            cout<<ans<<endl;
        }
        else {
            double ans=0;//ans是拿去舍掉的
            int fl=0;
            ll ans1=0,ans2=0;
            if(fir_neg!=0&&last_pos!=0){
                ans1=fir_neg,ans2=last_pos;
            }
            if(fir_pos!=0&&last_neg!=0){
                if(-1*fir_neg*last_neg>-1*fir_pos*last_pos)//十字相乘
                    ans1=fir_pos,ans2=last_neg;
            }
            if(ans1==0&&ans2==0){
                ll ans=1;
                for(int i=n;i>n-k;i--)ans=mul(ans,a[i]);
                cout<<ans<<endl;
            }
            else {
                ll ans=1;
                for(int i=1;i<=k;i++){
                    if(a[i]!=ans2)ans=mul(ans,a[i]);
                }
                ans=mul(ans,ans1);
                cout<<ans<<endl;
            }
        }
    }
    return 0;
}
举报

相关推荐

0 条评论