A. Morning
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
string s;
cin>>s;
int ans=0;
int j=1;
for (int i=0;i<4;i++){
int x=s[i]-'0';
if(s[i]=='0'){
x+=10;
}
if(x==j){
ans++;
}
else {
ans+=abs(x-j)+1;
j=x;
}
}
cout<<ans<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
B. Chemistry
思路:如果数量为奇数个的字符要大于k+1的话,则无法形成回文(每次k都可以使一个字符数量变为偶数,当只有一个字符数量为奇数时,可以放在中间)
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n,k;
cin>>n>>k;
string s;
cin>>s;
map<char,int> mp;
for (int i=0;i<n;i++){
mp[s[i]]++;
}
int cnt=0;
for (auto i : mp){
if(i.second%2){
cnt++;
}
}
if(cnt<=k+1){
cout<<"YES"<<endl;
}
else {
cout<<"NO"<<endl;
}
}
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
C. Raspberries
思路:本题k范围有限,可以分类讨论来解决。
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n,k;
cin>>n>>k;
vector<int> a(n);
int cnt=0;
for (int i=0;i<n;i++){
cin>>a[i];
if(a[i]%2==0){
cnt++;
}
}
int res;
if(k!=4){
res=5;
for (int i=0;i<n;i++){
res=min(res,k-(a[i]%k));
}
for (int i=0;i<n;i++){
if(a[i]%k==0){
res=0;
}
}
cout<<res<<endl;
}
else {
if(cnt>=2){
res=0;
}
else if (cnt==1){
res=1;
for (int i=0;i<n;i++){
if(a[i]%4==0){
res=0;
}
}
}
else {
res=2;
for (int i=0;i<n;i++){
if(a[i]%k==3){
res=1;
}
}
}
cout<<res<<endl;
}
}
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
//看清楚题
D. In Love
思路:如果最左端的r于最右端的l相交,则全部相交,否则存在不相交。
用两个set 来分别贮存l和r(set 自带排序功能,和两端指针)
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n;
cin>>n;
set<int> le,ri;
map<int,int> mp,mp1;
for (int i=1;i<=n;i++){
char a;
int l,r;
cin>>a>>l>>r;
if(a=='+'){
mp[l]++;
mp1[r]++;
le.insert(l);
ri.insert(r);
}
else {
mp[l]--;
mp1[r]--;
if(mp[l]==0){
le.erase(l);
}
if(mp1[r]==0){
ri.erase(r);
}
}
if(le.size() && ri.size() ){
auto a=le.end();
auto b=*ri.begin();
a--;
if(*a>b){
cout<<"YES"<<endl;
continue;
}
else {
cout<<"NO"<<endl;
continue;
}
}
cout<<"NO"<<endl;
}
}
signed main()
{
int t;
//cin>>t;
t=1;
while(t--){
solve();
}
}
E. Look Back
直接相乘会超时,每个数用ai*2^xi 表示。
当ai-1 < ai 让 xi 不断减一,直到 ai-1*2<ai.
当ai-1>ai xi不断加一,直到 ai>=ai-1.
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n;
cin>>n;
vector<int> a(n);
for (int i=0;i<n;i++){
cin>>a[i];
}
int cnt=0,res=0;
for (int i=1;i<n;i++){
int x=a[i-1];
int y=a[i];
int ans=0;
while(x<y){
ans--;
x*=2;
}
while(x>y) ans++, y*=2;
res=max((int)0,ans+res);
cnt+=res;
}
cout<<cnt<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}
F. You Are So Beautiful
思路:要作为唯一的子数组,左端的数必须时第一次出现的位置,否则会被取代,而贡献值由第一次出现的数提供,在最后出现的位置结算一次贡献,每出现一个数贡献加一,且不会消失。
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n;
cin>>n;
vector<int> a(n);
map<int,int> mp;
for (int i=0;i<n;i++){
cin>>a[i];
mp[a[i]]=i;//最后一次出现的位置。
}
int cnt=0,sum=0;
set<int> s;
for (int i=0;i<n;i++){
if(!s.count(a[i])){
s.insert(a[i]);
cnt++;//记录第一次出现的数的数量。
}
if(mp[a[i]]==i){
sum+=cnt;//如果为最后出现的位置则加上贡献。
}
}
cout<<sum<<endl;
}
signed main()
{
int t;
cin>>t;
while(t--){
solve();
}
}