P1106 删数问题

发布时间 2023-10-22 22:45:54作者: 加固文明幻景

P1106删数问题

对2018年的我一次完美的对位单杀

2018 44pts Code

#include<cstdio>
#include<iostream>
#include<algorithm>
using std::cin;
using std::cout;
using std::sort;
using std::pair;
using std::string;

string zsk_lu_ping;
struct zsksb
{
    int place;
    int w;
    bool operator < (const zsksb & rhs)
    const{
        return w>rhs.w;
    }
}zsk_chao_ti_jie[43534];
int d;
int vis[3434];
int main(void)
{
    cin>>zsk_lu_ping;
    cin>>d;
    for(int i=0;i<zsk_lu_ping.length();i++)
    {
        zsk_chao_ti_jie[i].place=i;
        zsk_chao_ti_jie[i].w=zsk_lu_ping[i]-'0';
    }
    sort(zsk_chao_ti_jie,zsk_chao_ti_jie+zsk_lu_ping.length());
    for(int i=0;i<d;i++)
    {
        vis[zsk_chao_ti_jie[i].place]=1;
    }
    for(int i=0;i<zsk_lu_ping.length();i++)
    {
        if(!vis[i])
        {
            cout<<zsk_lu_ping[i];
        }
    }
}

先来看看为什么错,2018年的做法是无脑找前K大的数,然后删去,这是存在问题的。

比如13928 2。如果按照这个算法,我会删去9、8,剩余的数是\(132\)。而显然删去3、9,剩余的数是128是一个更好的解法。

2023 72pts Code

#include <iostream>
using namespace std;

string s;
int k, minn, minP, sum;
char ans[300];

int main() {
	cin >> s >> k;
	for (int i = 0; i < s.length(); i++) {
		minn = 100;
		for (int j = i; j <= i + k; j++) {
			if (minn > s[j] - '0') {
				minn = s[j] - '0';
				minP = j;
			}
		}
		k -= minP - i;
		i = minP;
		ans[sum++] = s[minP];
	}
	for (int i = 0; i < sum; i++) {
		cout << ans[i];
	}
	return 0;
}

时隔五年,我重做这道题目,放下浮躁慢慢想。

我事先知道这是贪心,把题目转化为这样一个问题

从当前最高位开始,在右端k位中寻找最小值,将最小值转到最高位,并将最高位移至最小值所在位的下一位。k减去最小值移动的位数。

这是一个正确的贪心。但我没有处理ans中的前导零,处理完细节后拿下AC.

#include <iostream>
using namespace std;

string s;
int k, minn, minP, sum, isFirst;
char ans[300];

int main() {
	cin >> s >> k;
	for (int i = 0; i < s.length(); i++) {
		minn = 100;
		for (int j = i; j <= i + k; j++) {
			if (minn > s[j] - '0') {
				minn = s[j] - '0';
				minP = j;
			}
		}
		k -= minP - i;
		i = minP;
		ans[sum++] = s[minP];
	}
	for (int i = 0; i < sum; i++) {
		if (ans[i] == '0' && !isFirst) {
			continue;
		}
		isFirst = true;
		cout << ans[i];
	}
	if (!isFirst) {
		cout << 0;
	}
	return 0;
}