牛客周赛 Round 19

牛客周赛 Round 19

A. 小红的字符串大小写变换

题意:

小红拿到了一个仅由大小写字母组成的长度为n的字符串,她希望把前k个字母变成大写,后
n−k个字母变成小写,你能帮帮她吗?

代码:

#include <bits/stdc++.h>
using namespace std ;
const int max_N=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;

void solve(){
	int n,k;
    cin>>n>>k;
    string s;
    cin>>s;
    int sw='a'-'A';
    for(int i=0;i<s.size();i++){
        if(i<k){
            if(s[i]>='A'&&s[i]<='Z'){
                cout<<s[i];
            }else{
                s[i]-=sw;
                cout<<s[i];
            }
        }else{
            if(s[i]>='a'&&s[i]<='z'){
                cout<<s[i];
            }else{
                s[i]+=sw;
                cout<<s[i];
            }
        }
    }
    cout<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);

	int t=1;
	
//	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

B. 小红杀怪

题意:

小红在一个游戏里杀怪。这是个回合制游戏,小红和两只怪物相遇了。
第一只怪物有 a 血量,第二只怪物有 b 血量。
小红有两个技能:
第一个技能叫火球术,效果是对单体怪物造成 x 伤害。
第二个技能叫烈焰风暴,效果是对每只怪物造成 y 伤害。
小红想知道,自己最少使用多少次技能,可以击杀这两只怪物?(当怪物血量小于等于0时,视为被击杀)

思路:

枚举使用1-20次烈焰风暴

代码:

#include <bits/stdc++.h>
using namespace std ;
const int max_N=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;

void solve(){
    int a,b,x,y;
    cin>>a>>b>>x>>y;
    int ans=INF;
    for(int i=0;i<=22;i++){
        int a1=a-y*i;
        int b1=b-y*i;
        int num=i;
        if(a1>0){
            num+=a1/x;
            if(a1%x!=0){
                num++;
            }
        }
        if(b1>0){
            num+=b1/x;
            if(b1%x!=0){
                num++;
            }
        }
        ans=min(ans,num);
    }
    cout<<ans<<endl;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);

	int t=1;
	
//	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

C. 小红的元素分裂

题意:

小红拿到了一个数组,她每次可以进行如下操作之一:
·选择一个元素x,将其分裂为1和x−1。
·选择一个元素x,将其分裂为a和b,需要保证a∗b=x

小红希望用最少的操作次数,将所有数组的所有元素全部变成1。你能帮帮她吗?

思路:

动态规划,转移方程为dp[i]=min(dp[i-1]+1,dp[a]+dp[b]+1);a为可以整除i的所有数

代码:

#include <bits/stdc++.h>
using namespace std ;
const int max_N=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;


void solve(){
    int dp[max_N];
    dp[1]=0;
    for(int i=2;i<max_N;i++){
        dp[i]=dp[i-1]+1;
        for(int j=2;j*j<=i;j++){
            if(i%j==0){
                dp[i]=min(dp[i],dp[j]+dp[i/j]+1);
            }
        }
    }
    int n;
    cin>>n;
    int a[n+1];
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        ans+=dp[a[i]];
    }
    cout<<ans<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);

	int t=1;
	
//	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

D. 小红的扫雷游戏

题意:

小红最近爱上了扫雷游戏。
所谓扫雷游戏的规则是这样:给定一个nm的矩阵,每个位置有可能是地雷。如果点击了一个地雷,那么直接被炸死,游戏结束。如果点击的一个位置不是地雷,那么将显示该格子周围 8 个格子中地雷数量的总和。
“周围 8 个格子”的定义:对于一个点 (x,y),其周围 8 个格子的坐标为 (x+i,y+j) ,其中−1≤i,j≤1。
现在小红拿到了一个 4
4 的矩阵,其中有一些位置已经被翻开。小红想知道,根据现有的信息,有哪些位置一定是雷,有哪些位置一定不是雷?小红希望你能把地图标记上。

思路:

由于数据量很小,只有4*4,所以可以考虑暴力枚举所有方案,如果一个点周围没有任何数字,则这个点肯定未知,可以剪枝。这里枚举利用了dfs的可回溯性。所有方案中,若方案可行,可行方案数res加一,有雷的位置('X')cnt1加一,没雷的位置('O')cnt2加一。枚举完所有方案后,遍历每个点,若这个点出现雷的次数cnt1等于可行方案数,则这个点必定为雷;若这个点不出现雷的次数cnt2等于可行方案数,则这个点必定不为雷;否则为不确定点。

代码:

#include <bits/stdc++.h>
using namespace std ;
const int max_N=1e5+7;
const int INF = 0x3f3f3f3f;
typedef long long ll;

struct node {
    int x,y;
};

char s[6][6];

const int dx[]={-1,0,1,-1,1,-1,0,1},
          dy[]={-1,-1,-1,0,0,1,1,1};

//检查方案是否可行
int check(){
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            if(s[i][j]>='0'&&s[i][j]<='9'){
                int num=s[i][j]-'0';
                int count=0;
                for(int k=0;k<8;k++){
                    int x=i+dx[k];
                    int y=j+dy[k];
                    if(x<1||x>4||y<1||y>4){
                        continue;
                    }
                    if(s[x][y]=='X'){
                        count++;
                    }
                }
                if(num!=count){
                    return 0;
                }
            }
        }
    }
    return 1;
}

int cnt1[6][6],cnt2[6][6],res;

//检查这个点是否需要剪枝
int ismine(node st){
    int x,y;
    for(int i=0;i<8;i++){
        x=st.x+dx[i];
        y=st.y+dy[i];
        if(x<1||x>4||y<1||y>4){
            continue;
        }
        if(s[x][y]>='0'&&s[x][y]<='9'){
            return 1;
        }
    }
    return 0;
}

//枚举所有方案
void dfs(node t){
    if(t.x==5&&t.y==1){
        if(check()==1){
            res++;
            for(int i=1;i<=4;i++){
                for(int j=1;j<=4;j++){
                    if(s[i][j]>=0&&s[i][j]<='9'||s[i][j]=='.'){
                        continue;
                    }
                    if(s[i][j]=='X'){
                        cnt1[i][j]++;
                    }else{
                        cnt2[i][j]++;
                    }
                }
            }
        }
        return ;
    }
    node st;
    if(t.y<4){
        st.y=t.y+1;
        st.x=t.x;
        
    }else{
        st.y=1;
        st.x=t.x+1;
        
    }
    if(s[t.x][t.y]>='0'&&s[t.x][t.y]<='9'||ismine(t)==0){
        dfs(st);
        return ;
    }
    s[t.x][t.y]='X';
    dfs(st);
    s[t.x][t.y]='O';
    dfs(st);
}

void solve(){
	
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            cin>>s[i][j];
        }
    }
    node t;
    t.x=1,t.y=1;
    res=0;
    memset(cnt1,0,sizeof(cnt1));
    memset(cnt2,0,sizeof(cnt2));
    dfs(t);
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            if(s[i][j]>='0'&&s[i][j]<='9'||s[i][j]=='.'){
                continue;
            }
            if(cnt1[i][j]==res){
                s[i][j]='X';
            }else if(cnt2[i][j]==res){
                s[i][j]='O';
            }else{
                s[i][j]='.';
            }
        }
    }
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            cout<<s[i][j];
        }
        cout<<"\n";
    }
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);

	int t=1;
	
//	cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}

posted @ 2023-11-14 17:16  Beater_1117  阅读(212)  评论(0)    收藏  举报