题目:
小蓝的幸运数字是 ,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要 V次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
题解:
首先声明,本人只会70%的答案,更全会了再更新
蓝桥杯,顾名思义也是暴力杯,不管是什么题,直接暴力肯定没错
首先我们可以推出n个字符,最多可以构造的最多交换次数的状态就是倒序放字符,利用公式n * (n-1)/2可以求出最多用多少字符可以表示答案,同时也求出答案的长度。然后。。就dfs就行了。。先假设每个字符都出现一次,然后最小的字符出现两次,然后依次增加,,,
剪枝优化优化就可以了,70%
好像直接暴力就行,也不用先求长度
代码:
#include <bits/stdc++.h>using namespace std;const int N = (int)1e4+5;int num[N], res[N];
int n, m, _max, len;bool judge(int letter)
{int i = 26, j = letter;while (!res[i]) i--;if (i == j) {while (i > 0 && j > 0) {if (res[i] != num[j]) {return res[i] > num[j];} else {i--;j--;}}}return i > j;
}void dfs(int letter, int curlen, int cursum, int l) {if (cursum > n) return ;if (letter > _max) return ;if (curlen > len) return ;if (curlen == len && cursum != n) return ;if (letter == _max && cursum != n) return ;if (cursum == n) {if (curlen < len || judge(letter)) { //长度减小或字典序减小更新结果len = curlen;for (int i = 1; i <= 26; i++) {res[i] = num[i];}}return ;}for (int i = 1; i <= l; i++) {num[letter + 1] = i;dfs(letter + 1, curlen + i, cursum + i * curlen, i);}num[letter + 1] = 0;
}int main() {scanf("%d", &n);m = 0; len = 0;
// int pos;
// for(int i=1;i;i++)
// {
// if(i*(i-1)/2>=n)
// {
// pos=i;
// res[i]=1;
// break;
// }
// res[i]=1;
// }
// m=pos*(pos-1)/2;
// _max=pos;
// len=pos;while (m < n) {int id = 1;for (int i = 2; i <= 26; i++) { //找到s最小的点, 如果存在多个取字典序更小的if (res[i] < res[id]) id = i;}m += len - res[id];_max = max(_max, id);len ++; res[id] ++;}dfs(0, 0, 0, 10);for (int i = _max; i >= 1; i--) {for (int j = res[i]; j > 0; j--) {printf("%c", i-1+'a');}}printf("\n");return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
char ans[N], res[N];
int n, len;
bool judge()
{int i = len;while(ans[i] == res[i] && i) i--;return res[i] < ans[i];
}
void dfs(int now, int maxn, int m, int sum) {if(sum == n) {if(m < len || (m == len && judge())){len = m;for(int i = 1; i <= len; i++) ans[i] = res[i];}return;}if(now >= 26) return ;for(int i = 1; i <= maxn; i++) {int temp = sum + m * i;if(temp > n) return ;res[m + i] = char(now + 'a');dfs(now + 1, i, m + i, temp);}
}int main()
{len = 0x3f3f3f3f;scanf("%d", &n);dfs(0, 8, 0, 0);for(int i = len; i >= 1; i--)putchar(ans[i]);return 0;
}