8.13科大讯飞研发卷2
3道编程50分加50分的选择。
1、a[a[i]] = n - a[i] + 1,i和a[i]范围都是1~n。求字典序最大的数组a。直接输出倒序即可。
2、一个字符串str,从str[i]走到str[i+1]需要str[i+1]-str[i]的体力,若为负数则会加体力。现在初始体力为k,求是否能从str[0]走到str[n],若能输出剩余体力,若不能输出-1。
简单模拟即可。
int main(void){
int n, k;
cin >> n >> k;
getchar();
string str;
cin >> str;
for (int i = 0; i < n - 1; i++){
k -= str[i+1] - str[i];
if (k < 0){
cout << -1 << endl;
return 0;
}
}
cout << k << endl;
return 0;
}
3、有两个长度为n的数组nums1和nums2,都是由1~n的元素组成,且元素各不相同。现在要存储它们的子数组,相同的子数组可以只存储一次,求最少需要存储多少个子数组。
如[1,2,3]和[3,1,2]只需存储[1],[2],[3],[1,2],[2,3],[3,1],[1,2,3],[3,2,1]等8个子数组。
求出不相同的子数组个数即可,设dp[i]为nums1中以nums1[i]为结尾且不在nums2中的子数组数目,dp2[i]为nums1中以nums1[i]为结尾的所有子数组数目。则有:
- 若序列{nums1[i-1], nums1[i]}不在nums2中:dp[i+1] = dp2[i]
- 否则:dp[i+1] = dp[i]
因为两个数组的不同子数组个数和相同子数组个数都相同,则结果即为all+differentNum,all为所有子数组个数为n*(n+1)/2。
int main(void){
int n;
cin >> n;
vector<int> nums1(n);
for (int i = 0; i < n; i++)
cin >> nums1[i];
set<pair<int, int>> st;
int pre = -1, tmp;
for (int i = 0; i < n; i++){
cin >> tmp;
st.insert({pre, tmp});
pre = tmp;
}
long long dp = 0, dp2 = 1;
long long differentNum = 0;
for (int i = 1; i < n; i++){
if (!st.count({nums1[i-1], nums1[i]}))
dp = dp2;
dp2++;
differentNum += dp;
}
long long all = 1LL * n * (n+1) / 2;
cout << all + differentNum << endl;
return 0;
}
#科大讯飞信息集散地#

