目录
A - Keanu Reeves
题意:一个01字符串S,把它分成K段,使得每段的0的数量不等于1的数量,让K尽可能的小。
输出分成的段数和分完后的K段。
思路:
如果0和1的数量不等,分成一段;相等,分成两段。和
。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
string s;
cin>>n;
cin>>s;
int cnt0=0,cnt1=0;
for(int i=0;i<n;i++)
{
if(s[i]=='0')
cnt0++;
else
cnt1++;
}
if(cnt0!=cnt1)
{
cout<<"1"<<endl;
cout<<s<<endl;
}
else
{
cout<<"2"<<endl;
cout<<s[0]<<" ";
for(int i=1;i<n;i++)
cout<<s[i];
cout<<endl;
}
}
B - Number Circle
题意:给你n个数,用这n个数构造一个序列,使得它们围成圆圈后,每个数都严格小于左右邻居的和。
思路:
对数组排序。
如果则不行,其他情况都可以。
对数组排完序后,除了1和n之外,其他的点都可以满足条件。因为,所以一定
。但是
不一定小于
。所以,我们让
和
交换位置。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxx=1e5+10;
int a[maxx];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+1+n);
if(a[n]>=(a[n-1]+a[n-2]))
cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
cout<<a[n]<<" "<<a[n-1];
for(int i=1;i<=n-2;i++)
{
cout<<" "<<a[i];
}
cout<<endl;
}
}
C - Candies!
题意:给你一个数组(
),
个区间,每个区间的长度
。
有一种操作是把奇数位和偶数位相加 用和来代替之前的两个数。如果和大于等于10就要,并且答案计数
。每一个区间奇数位和偶数位不断相加取模处理。问最后只剩一个数的时候,取了几次模。
思路:
每一个区间最后都是操作到只剩一位的,因为,每次操作都有一个10答案数加1,可以直接将区间的值累和,判断总和可以有几个10。所以直接前缀和然后再除10。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxx=1e5+10;
int a[maxx];
int sum[maxx];
int main()
{
int n,m,l,r;
memset(sum,0,sizeof(sum));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
cin>>m;
while(m--)
{
cin>>l>>r;
int ans=(sum[r]-sum[l-1])/10;
cout<<ans<<endl;
}
}
D - Add on a Tree
题意:给你一棵有n个节点的树。一开始,所有的边都是0。在一个操作中,你可以选择任意2个不同的叶子u, v和任何实数x,并将x加到u和v之间路径上的所有边上。问,是否可以实现构造后的树让每一条边都为任意值。
思路:
样例二解释:选取任意的两个叶子节点,这个样例只能选择1和3,这两个节点连接的边都加x,
不论怎么加,这两条边的值都相等,这两条边就像绑定了,不能实现让任一条边为任意值。
样例三解释:选取任意的两个叶子节点3,4之后,(3,1)(4,1)权值相等了,但是可以通过(5,2,1,4)加个x,使得(3,1)(4,1)的权值不等,可见,当一个顶点连接三条边的时候可以实现让任一条边为任意值。但是,该样例中(5,2)(2,1)具有绑定关系,我要经过2顶点,必须同时走(5,2)(2,1)。
如果一个节点有两条边,它肯定不是叶子节点,向下可以找到至少一个叶子节点,形成集合U(如图中7),向上可以找到其他的叶节点(如4,5,6)形成集合V。U,V交集为空。
任意U中的的叶节点到V都只能经过刚刚找到的节点相连的两条边,所以这两条边边权相等。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxx=1e5+10;
int d[maxx];
int main()
{
int n,u,v;
cin>>n;
memset(d,0,sizeof(d));
for(int i=1;i<n;i++)
{
cin>>u>>v;
d[v]++;
d[u]++;
}
int f=0;
for(int i=1;i<=n;i++)
{
if(d[i]==2)
{
f=1;
}
}
if(f==1)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
E - Count Pairs
题意:
思路:
两边同时乘
移项:
遍历,求,前面出现过几个与该值相等的ans就累加次数(map)。
注意可能小于零,所以要加个p。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,ll>m;
int main()
{
ll n,p,k,x,tmp;
ll ans=0;
cin>>n>>p>>k;
for(int i=0;i<n;i++)
{
cin>>x;
tmp=x*x%p*x%p*x%p;
tmp=(tmp-(k*x%p)+p)%p;
ans+=m[tmp];
m[tmp]++;
}
cout<<ans<<endl;
}