社区讨论
0分,求,悬棺
P1323删数问题参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mjxo44na
- 此快照首次捕获于
- 2026/01/03 10:12 2 个月前
- 此快照最后确认于
- 2026/01/06 14:35 2 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 3 * 1e4 + 5;
int k , m;
int a[N];//第i位数字
bool eat[N];//是否被删除
string num;//存数字
void into(){//预处理
a[1] = 1;
int xx = 1 , yy = 1;
int toooot = 3 * 1e4;
for(int i = 2;i <= toooot;i ++){
if(a[xx] * 2 + 1 < a[yy] * 4 + 5){
a[i] = a[xx ++] * 2 + 1;
}else{
a[i] = a[yy ++] * 4 + 5;
}
}
}//其中flag表示是否进行了删除行为 , 返回值表示是否还能再删除
char get_next(int now){//获得未被删除的下一位数的位置
int len = num.length();
while(1){
now ++;
if(eat[now] == 0){
return now;
}else if(now == len){
return len;
break;
}
}
}
bool to_eat(bool &flag){//进行一轮删除
int len = num.length();
flag = 0;
for(int i = 0;i < len;i ++){
if(eat[i]){
continue;
}if(m == 0){
return 1;
}
if(num[i] < num[get_next(i)]){
eat[i] = 1;
flag = 1;
m --;
}
}
if(m == 0){
return 1;
}
return 0;
}
void to_end(){//最后从后往前删除
int i = num.length();
while(m){
i --;
if(eat[i] == 0){
eat[i] = 1;
m --;
}else{
continue;
}
}
}
signed main(){
cin >> k >> m;
into();
for(int i = 1;i <= k;i ++){
// cout << a[i];
num += to_string(a[i]);
}
cout << num;
while(1){
bool flag;
if(to_eat(flag) == 1 || flag == 0){//删除完毕或者无法继续删除
break;
}
}
cout << endl;
to_end();
int len = num.length();
for(int i = 0;i < len;i ++){
if(eat[i] == 0){
cout << num[i];
}
}
return 0;
}
大概思路:
先预处理所有数,然后从前往后开始,只要该数比后面一位小就删除(在代码中通过
eat[i] 来表示是否被删除)get_next(int now) 表示第 位后第一个没被删除的位置。bool to_eat(bool &flag) 进行一次删除操作,其中 flag 为本次是否删除了数,返回值表示是否删够了数。如果删够了或者没有进行删除操作则从后面开始删除剩余的 个数(to_end() 实现)。回复
共 0 条回复,欢迎继续交流。
正在加载回复...