牛客周赛 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。
现在小红拿到了一个 44 的矩阵,其中有一些位置已经被翻开。小红想知道,根据现有的信息,有哪些位置一定是雷,有哪些位置一定不是雷?小红希望你能把地图标记上。
思路:
由于数据量很小,只有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;
}

浙公网安备 33010602011771号