A、C两道题题解
一.A题
(1)题意:
t 组测试数据,每组数据有 n 个数 ai,代表着 si 行字符串与 s(i-1)行字符串有多少个 ai 相同前缀字符
每组测试数据输出 n + 1行字符串,第二行开始与前一行有 ai 个相同前缀字符
(2)题解:
- 第 i 行的字符串的长度应该是 max(ai,a(i+1))决定 ,利用一个str数组来存储字符的变化情况,初始化为全部相同字符
- 所以第一行先输出一个全部相同的字符串,并且长度为最长,例如:aaaaaaa 方便后面输出
- 从第二行开始,每一行先输出str数组中相同前缀,然后假如下一行的前缀数 a(i+1) > ai 还得把str数组中的字符 + 1输出 a(i+1) - ai次
(3)代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int t,n,a[maxn];
char str[200];
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d",&n);
fill(str,str+110,'a');
memset(a,0,sizeof(a));
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
printf("%s\n",str);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= a[i]; j++)
printf("%c",str[j]);
for(int j = a[i] + 1; j <= a[i + 1] + 1; j++)
{
str[j] = (str[j] + 1) % 123;
if(str[j] < 97)
str[j] += 97; //限定为小写英文字母的ascii值
printf("%c",str[j]);
}
printf("\n");
}
}
return 0;
}
二.C题
(1)题意:
给t组数据,长度为 n 的两个字符串 s1,s2 ,可以选择一个位置 k ,然后将s1[i] ~ s1[k]中等于s1[k]的字符都变成另外一个大于s1[k]的字符
例如 acbbdb 就可以把第三位、第四位、第六位的 b 都变成任何一个大于 b 的字符,例如变成 acccdc 或者 acdddd ……
当有s1[i] > s2[i]的字符存在时候,输出-1
问最少能用几次把s1串变成s2串
(2)题解:
贪心的想法 – 尽量一次能够变化多的字符可能会最省次数,字符变化成多少由最小的对应s2串的值决定
例如:s1 : aab s2 : bcc
就只能aa -> bb — bbb,然后在 bb -> cc — bcc
(3)代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 30;
int t,flag,n,ans;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
string s1,s2;
cin>>s1>>s2;
flag = 0;
ans = 0;
vector <int> v[maxn];
for(int i = 0; i < n; i++)
{
if(s1[i] > s2[i])
flag = 1;
else if(s1[i] < s2[i])
v[s1[i] - 'a'].push_back(i);
//根据s1[i]的字符大小,把 i 分成不同类
}
if(flag == 1)
{
printf("-1\n");
continue;
}
for(int i = 0; i < 20; i++)
{ //从小到大开始遍历 'a' -> 't'
char minn = 'z'; //把minn初始化设置为一个不会影响结果的值
int num = v[i].size();
if(num > 0)
ans++;
// num中有值,说明需要一次修改
for(int j = 0; j < num; j++)
minn = min(minn,s2[v[i][j]]);
//把相同s1串的值改为最小的那个s2串对应位置的值
for(int j = 0; j < num; j++)
if(s2[v[i][j]] > minn)
v[minn - 'a'].push_back(v[i][j]);
//修改之后,这些相同的s1串的值就变成了 minn
//然后再把剩下的这些加入到对应的 v[minn - 'a'] 位置去
}
printf("%d\n",ans);
}
return 0;
}