A. Equidistant Letters
找到相同的字母,相同的字母先排一遍,然后再按第一次排的顺序排一遍。
独有的字母就排在后面就行
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5+5;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
vector<int>cnt(26);
char s[55];
scanf("%s",s);
for(int i=0;i<strlen(s);i++)
cnt[s[i]-'a']++;
vector<int>a,b;
for(int i=0;i<26;i++)
{
if(cnt[i]==2) a.push_back(i);
else if(cnt[i]==1) b.push_back(i);
}
for(auto i : a) cout<<(char)(i+'a');
for(auto i : a) cout<<(char)(i+'a');
for(auto i : b) cout<<(char)(i+'a');
cout<<endl;
}
return 0;
}
B. Minor Reduction
考虑几种情况:
根据优先级进行:
- 最高:
两个相邻的数字相加结果为2
位,结果大于原来的两个相邻的数。遍历顺序为从前往后。
但是,此种情况不存在,最大也就9 + 9 =18
,18也还是小于99 - 中等:
相邻两个数相加结果位数为2
位,但是结果比原来小。遍历顺序为从后往前。因为要是前面的话一变小,高位会首先变小,数字肯定变得更小,要是从低位开始遍历,虽然变小,但是变化的是低位的数字,不至于变得更小。 - 最低:
两个相邻数字相加结果为1
位,结果肯定还是变小。遍历顺序为从前往后。相加虽然变成一位,但是该位的数字变得更大了,在高位相对不会变得更小。
该种情况可以简化:对第一个数字和第二个数字做加和运算即可
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5+5;
void solve()
{
string s;
cin>>s;
//中等
for(int i=s.size()-2;i>=0;i--)
{
int x = s[i]-'0' + s[i+1]-'0';
int cur = (s[i]-'0')*10 + s[i+1]-'0';
if(x <= cur && x>=10)
{
string t = to_string(x);
s[i] = t[0];
s[i+1] = t[1];
for(auto a:s) cout<<a;
cout<<endl;
return ;
}
}
//最低
int x = s[0]-'0' + s[1]-'0';
cout<<x;
for(int i=2;i<s.size();i++) cout<<s[i];
cout<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
C. Monsters And Spells
以由简到复杂的思路进行分析:
- 只有一个怪兽。它在
k
k
k秒出现,血量为
h
h
h,那么在
k
−
h
+
1
k-h+1
k−h+1秒时,攻击力要为
1
,即攻击力递增区间为 [ k − h + 1 , k ] [k-h+1,k] [k−h+1,k],总消耗值为 1 + 2 + . . . + h = h ( h + 1 ) 2 1+2+...+h=\frac{h(h+1)}{2} 1+2+...+h=2h(h+1) - 有两个怪兽。
- 如果两个怪兽出现互不干扰(就是后面出现的怪兽需要变为1的时间点在第一个怪兽出现时间点的后面),还是上面的计算方法,两个分别计算即可。
- 两个怪兽(设为
i
和j
, k i < k j k_i<k_j ki<kj)干扰了。 两个区间本来为 [ k i − h i + 1 , k i ] , [ k j − h j + 1 , k j ] [k_i-h_i+1,k_i],[k_j-h_j+1,k_j] [ki−hi+1,ki],[kj−hj+1,kj],出现干扰交叉也就是 k j − h j + 1 < = k i k_j-h_j+1<=k_i kj−hj+1<=ki了。本来这里应该变成1
的(这个位置如果是1的话见下),但是这又在i
的地方,这时攻击力必须为 h i h_i hi才能灭掉怪兽,所以后面必须递增下去,即 [ k j − h j + 1 , k j ] [k_j-h_j+1,k_j] [kj−hj+1,kj]区间是递增的,初值不再是1
,而是接着前面的进行递增变化。
漏了一点,当 k j − h j + 1 < = k i − h i + 1 k_j-h_j+1<=k_i-h_i+1 kj−hj+1<=ki−hi+1时,这个位置还可以是1
可以发现: 两个递增区间有交集,那么结果就是两个区间的并集,然后求总和。区间长度为len
,结果就为 l e n ( l e n + 1 ) 2 \frac{len(len+1)}{2} 2len(len+1)
- 三个怪兽。
不干扰还是各算各的。干扰的话就是求区间的并集,区间长度也可以求出,也可以算出结果。 - 总结下来:就是所有怪兽的攻击力递增区间求并集,对于每个合并后的大区间,攻击力是从1开始递增的。
那么这样就很好解决了,求出所有的区间,区间合并,求一下交集,同时记录结果即可。
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e5+5;
void solve()
{
int n;
cin>>n;
vector<pair<int,int>>p(n);
vector<int>k(n),h(n);
for(auto &i : k) cin>>i;
for(auto &i : h) cin>>i;
for(int i=0;i<n;i++)
p[i] = {k[i]-h[i]+1,k[i]};
sort(p.begin(),p.end());
ll res = 0 ;
ll l = 0,r = 0;
for(int i=0;i<n;i++)
{
if(p[i].first > r)
{
if(l && r) res += (r-l+1)*(r-l+2)/2;
l = p[i].first;
r = p[i].second;
}
else r = max((ll)p[i].second,r);
}
res += (r-l+1)*(r-l+2)/2;
cout<<res<<endl;
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
往期优质文章推荐
领取大量学习资源