A. Skibidus and Amog'u
思路:把字符串最后的us变成i就可以了,水题一个
#include <iostream>
#include <string>
int main() {
int t;
std::cin >> t;
std::cin.ignore();
while (t--) {
std::string W;
std::getline(std::cin, W);
if (W.length() >= 2 && W.substr(W.length() - 2) == "us") {
std::string root = W.substr(0, W.length() - 2);
std::string plural = root + "i";
std::cout << plural << std::endl;
}
}
return 0;
}
B. Skibidus and Ohio
思路,有一对相邻的相同就可以把整个序列的长度变成1,否则就是原长度
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[200005];
string s;
void solve()
{
cin>>s;
for(int i=0;i<s.size()-1;i++)
{
if(s[i]==s[i+1])
{
cout<<1<<"\n";
return ;
}
}
cout<<s.size()<<"\n";
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
C1. Skibidus and Fanum Tax (easy version)
思路:本题b数组只有一个数,那么我们将a数组所有数都与b数组进行计算,
我们设x=a[i],y=b[i]-a[i],
1.假设x和y都大于等于前面一个,我们就选择min(x,y)作为a[i]
2.如果只有x大于等于前面一个,就选择x作为a[i]
3.如果只有y大于等于前面一个,就选择y作为a[i]
4.如果都不大于,就输出NO结束这次测试数据
如果运行到最后就是输出YES
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,m;
int a[200005];
int b[200005];
string s;
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=m;i++)
{
cin>>b[i];
}
a[0]=-0x3f3f3f3f;
int flag=1;
for(int i=1;i<=n;i++)
{
if(b[1]-a[i]<=a[i]&&b[1]-a[i]>=a[i-1])
{
a[i]=b[1]-a[i];
}
else if(b[1]-a[i]>=a[i-1]&&a[i]<a[i-1])
{
a[i]=b[1]-a[i];
}
if(a[i]<a[i-1])
{
flag=0;
break;
}
}
if(flag==0)
{
cout<<"NO\n";
}
else
{
cout<<"YES\n";
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
C2. Skibidus and Fanum Tax (hard version)
思路:一眼二分,我们还是上面的处理思路,但是我们该如何选取b[j]-a[i]呢?
我们可以用lower_bound去寻找第一个大于a[i]+a[i-1]的b[i]的位置,找到之后,就是c1的处理方式,直接去操作就可以了
分四步走战略
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,m;
int a[200005];
int b[200005];
string s;
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=m;i++)
{
cin>>b[i];
}
b[m+1]=1e12;
sort(b+1,b+1+m);
a[0]=-1e12;
a[1]=min(a[1],b[1]-a[1]);
for(int i=2;i<=n;i++)
{
int flag=a[i-1]+a[i];
int pos=lower_bound(b+1,b+2+m,flag)-b;
if(pos==m+1&&a[i]<a[i-1])
{
cout<<"NO\n";
return ;
}
else if(pos>=1&&pos<=m&&a[i]<a[i-1]&&b[pos]-a[i]>=a[i-1])
{
a[i]=b[pos]-a[i];
}
else if((pos>=1&&pos<=m&&a[i]>=b[pos]-a[i]&&b[pos]-a[i]>=a[i-1]))
{
a[i]=b[pos]-a[i];
}
}
cout<<"YES\n";
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
D. Skibidus and Sigma
思路:其实就是按照顺序单行数组的累加和大小排序就行,然后计算一遍累加和就过了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,m;
int x;
int sum;
string s;
pair<int,int> p[200005];
void solve()
{
cin>>n>>m;
int a[n+1][m+1];
for(int i=1;i<=n;i++)
{
sum=0;
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
sum+=a[i][j];
}
p[i].first=sum;
p[i].second=i;
}
sort(p+1,p+1+n);
sum=0;
int ans=0;
for(int i=n;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
sum+=a[p[i].second][j];
ans+=sum;
}
}
cout<<ans<<"\n";
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
E. Skibidus and Rizz
思路:我们首先要排除两种可能得情况
1,n<k,m<k,如果都小于k,就算单纯连起来也不可能达到要求,直接输出NO
2,abs(n-m)>k,整体都大于k了,呢么已经超过了最大平衡值k,所以不满足直接输出NO
3.否则,我们就先用最多的数构建一个长度为k的序列,如果是0,那么后续就跟10,直到其中一个没有了,如果剩下的是0,就补到最后面,如果剩下的是1,就补到前面,反之依然,就可以解决了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,m,k;
int a[200005];
void solve()
{
cin>>n>>m>>k;
if(abs(n-m)>k)
{
cout<<-1<<"\n";
}
else if(k>n&&k>m)
{
cout<<-1<<"\n";
}
else
{
string s="";
if(n>=m)
{
n-=k;
for(int i=1;i<=k;i++)
{
s+="0";
}
for(int i=1;i<=min(n,m);i++)
{
s+="10";
}
if(n>=m)
{
for(int i=1;i<=n-m;i++)
{
s+="0";
}
}
else
{
for(int i=1;i<=m-n;i++)
{
s+="1";
}
}
}
else
{
m-=k;
for(int i=1;i<=k;i++)
{
s+="1";
}
for(int i=1;i<=min(n,m);i++)
{
s+="01";
}
if(n>=m)
{
for(int i=1;i<=n-m;i++)
{
s+="0";
}
}
else
{
for(int i=1;i<=m-n;i++)
{
s+="1";
}
}
}
cout<<s<<"\n";
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
F. Skibidus and Slay
思路:直接去寻找每一个点链接的子节点,只要出现的次数大于等于2,就可以将其标注为1
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[500005];
int u,v;
vector<int> e[500005];
string s;
void dfs(int v,int fa,vector<int> &vis)
{
map<int,int> mp;
mp.clear();
mp[a[v]]++;
for(int u:e[v])
{
mp[a[u]]++;
if(mp[a[u]]==2)
{
vis[a[u]]=1;
}
}
for(int u:e[v])
{
if(u!=fa)
{
dfs(u,v,vis);
}
}
}
void solve()
{
cin>>n;
vector<int> vis(n+1,0);
for(int i=1;i<=n;i++)
{
e[i].clear();
}
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n-1;i++)
{
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,-1,vis);
for(int i=1;i<=n;i++)
cout<<vis[i];
cout<<"\n";
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
solve();
return 0;
}
G. Skibidus and Capping
思路:直接找到1~200000,里面的所有的素数,我们只需要统计三种情况的结果即可,
1,如果是素数的话,要找到所有和他能匹配的素数
2.如果是pq和pq的话,我们直接计算即可
3.如果是pq的话,我们要找到所有的p和q的数量
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[200005];
int pri[200005];//素数集合
int vis[200005];//判断是否是素数
int cnt=0;//统计素数数量
int p[200005];//每个数的最小质数
int shu[200005];
void ini()
{
vis[1]=1;
for(int i=2;i<=200000;i++)
{
if(vis[i]==0)
{
cnt++;
pri[cnt]=i;
}
for(int j=1;j<=cnt&&i*pri[j]<=200000;j++)
{
vis[i*pri[j]]=1;
p[i*pri[j]]=pri[j];
if(i%pri[j]==0)
break;
}
}
}
//三种情况
//1.两个都是素数
//2.pq和pq这种
//3.p和pq这种
void solve()
{
cin>>n;
int num=0;//用于统计素数个数
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(vis[a[i]]==0)
{
num++;
}
shu[a[i]]++;
}
int ans=(num+1)*num/2;
for(int i=2;i<=n;i++)
{
//第一种
if(vis[i]==0)
{
ans-=shu[i]*(shu[i]+1)/2;
continue;
}
int q=i/p[i];
if(vis[q]==1)
{
continue;
}
//第二种
ans+=shu[i]*(shu[i]+1)/2;
//第三种
ans+=shu[i]*shu[p[i]];
if(q!=p[i])
{
ans+=shu[i]*shu[q];
}
}
cout<<ans<<"\n";
for(int i=1;i<=200000;i++)
{
shu[i]=0;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ini();
cin>>t;
while(t--)
solve();
return 0;
}