Codeforces Round #572(div2)部分题解(A~C,E)
作者:互联网
目录
- 前言
- A - Keanu Reeves(思维+水题)
- B - Number Circle(数学+思维)
- C - Computer Game (思维)
- D - Add on a Tree
- E - Count Pairs (数学)
前言
你们知道在《Young Sheldon》第五季开播之前的那段时间里,我是怎么度过的吗?
你们知道我的痛楚吗?
哦,我记得我好像又把TBBT看了一遍,还顺便刷了老友记和权游。
我好像还挺快乐的,nmsl ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄。
8多说了,写完题解看我的谢耳朵去了(# ^ . ^ #)
A - Keanu Reeves(思维+水题)
比赛链接:https://codeforces.com/problemset/problem/1189/A
题目大意
给出一个只有
01
01
01组成的长度为
n
n
n的字符串
s
s
s。
我们认为如果一个字符串中
01
01
01的数量不等,那么这个字符串就是一个好的字符串。
现在需要你把字符串
s
s
s划分成
k
(
k
>
=
1
)
k(k>=1)
k(k>=1)个字符串 ,使得每个字符串都是好的。
问
k
k
k最小可以是多少,并且输出划分之后的结果。
思路
简单的思维题。
首先先判断
s
s
s本身是否就是一个好的字符串,如果是就直接输出即可。
否则我们只需要把第一个字符单拿出来,剩下的作为另一个字符,这两个字符串一定都是好的。
从另一个角度来想,长度为奇数的字符串一定是好字符串。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int main()
{
int n,a,b;
a=b=0;
cin>>n;
string ss;
cin>>ss;
for(int i=0;i<n;i++)
{
if(ss[i]=='1') a++;
else b++;
}
if(a==b) cout<<"2"<<endl<<ss[0]<<" "<<ss.substr(1,n-1)<<endl;
else cout<<"1"<<endl<<ss<<endl;
}
B - Number Circle(数学+思维)
比赛链接:https://codeforces.com/problemset/problem/1189/B
题目大意
给你n个数字
a
1
,
a
2
,
…
,
a
n
a_1, a_2, \ldots, a_n
a1,a2,…,an。
现在你需要把这些数字填到一个有n个空位的圆环里,并使得圆环中满足条件:
任意一个数字都严格小于与它相邻的两个数字的和。
不可以的话输出NO
。
可以的话第一行输出YES
,第二行输出一种可行的排列顺序
a
1
,
a
2
,
…
,
a
n
a_1, a_2, \ldots, a_n
a1,a2,…,an,其中
a
1
a_1
a1与
a
2
、
a
n
a_2、a_n
a2、an相邻。
思路
又是一道简单的思维题。
我们给所有的数从小到大排个序,之后我们去想:哪些数字最有可能不满足条件。
很显然就是最大的那个数字。
那么我们就需要给它安排两个好♂邻居,让它老实一点。
那么输出NO
的情况就推断出来了:最大的数比其他任意两个数的和都大。
否则我们就让最大的数
a
a
a、第一个小于
a
a
a 的数
b
b
b 和第二个小于
a
a
a 的数
c
c
c交换一下位置,让
b
b
b和
c
c
c把
a
a
a包围住。
原本的顺序:c b a
交换之后:c a b
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int a[maxn];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
if(a[n-1]>=a[n-2]+a[n-3]) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
for(int i=0;i<n-3;i++)
cout<<a[i]<<" ";
cout<<a[n-2]<<" "<<a[n-1]<<" "<<a[n-3]<<endl;
}
}
C - Computer Game (思维)
比赛链接:https://codeforces.com/problemset/problem/1189/C
题目大意
给一个长度为 n n n的数组 s s s。
规定函数
f
(
l
,
r
)
f(l,r)
f(l,r)的含义为:
(
s
s
s
l
l
l,
s
s
s
l
+
1
l+1
l+1,
…
\ldots
…,
s
s
s
r
r
r)的和整除10的值。
有q次询问,每次都询问一个 f ( l i , r i ) f(l_i,r_i) f(li,ri)的值。
思路
纯纯的前缀和入门题。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
int s[maxn];
int main()
{
int n;
cin>>n;
s[0]=0;
for(int i=1;i<=n;i++){
cin>>s[i];
s[i]+=s[i-1];
}
int q;
cin>>q;
for(int i=0;i<q;i++){
int l,r;
cin>>l>>r;
cout<<(s[r]-s[l-1])/10<<endl;
}
}
D - Add on a Tree
比赛链接:https://codeforces.com/problemset/problem/1189/D
看不懂的一道题,题意读不懂,再观望一下大佬们的博客。
E - Count Pairs (数学)
比赛链接:https://codeforces.com/problemset/problem/1189/E
题目大意
给你一个素数 p p p,一个长度为 n n n的数组 a a a和一个整数 k k k。
找出符合以下条件的 ( i , j ) ( 1 < = i < j < = n ) (i,j)(1<=i<j<=n) (i,j)(1<=i<j<=n)的数量。
( a i + a j ) ( a i 2 + a j 2 ) ≡ k m o d p (a_i + a_j)(a_i^2 + a_j^2) \equiv k \bmod p (ai+aj)(ai2+aj2)≡kmodp
思路
这题也是十分的简单,就是卡精度卡的很死, l o n g long long l o n g long long才过去的。
我们只需要调整一下原本的公式。
首先我们取原本的公式为①式:
①
(
a
i
+
a
j
)
(
a
i
2
+
a
j
2
)
≡
k
m
o
d
p
(a_i + a_j)(a_i^2 + a_j^2) \equiv k \bmod p
(ai+aj)(ai2+aj2)≡kmodp
这个式子给人一种不舒服的感觉,总感觉可以再化简一下。
我的初中老师曾教导我们:
看到式子里只有
(
a
−
b
)
(a-b)
(a−b)或是
(
a
+
b
)
(a+b)
(a+b)的时候,你就应该十分警觉地想到完全平方公式和平方差公式。
此时如果两边乘上
(
a
i
+
a
j
)
(a_i + a_j)
(ai+aj)形成完全平方公式,貌似又把问题加重了。
但如果我们让①式的两边同时乘上
(
a
i
−
a
j
)
(a_i - a_j)
(ai−aj)形成平方差公式②:
②
(
a
i
−
a
j
)
∗
(
a
i
+
a
j
)
(
a
i
2
+
a
j
2
)
≡
(
a
i
−
a
j
)
∗
k
m
o
d
p
(a_i - a_j)*(a_i + a_j)(a_i^2 + a_j^2) \equiv (a_i - a_j)*k \bmod p
(ai−aj)∗(ai+aj)(ai2+aj2)≡(ai−aj)∗kmodp
化简一下得到③:
③
(
a
i
2
−
a
j
2
)
(
a
i
2
+
a
j
2
)
≡
(
a
i
−
a
j
)
∗
k
m
o
d
p
(a_i^2 - a_j^2)(a_i^2 + a_j^2) \equiv (a_i - a_j)*k \bmod p
(ai2−aj2)(ai2+aj2)≡(ai−aj)∗kmodp
再化简一下得到④:
④
(
a
i
4
−
a
j
4
)
≡
(
a
i
−
a
j
)
∗
k
m
o
d
p
(a_i^4 - a_j^4) \equiv (a_i - a_j)*k \bmod p
(ai4−aj4)≡(ai−aj)∗kmodp
此时,我们觉得,把
a
i
a_i
ai和
a
j
a_j
aj放到全等号的两边会更好看一些。
处理一下得到⑤:
⑤
(
a
i
4
−
a
i
∗
k
)
m
o
d
p
≡
(
a
j
4
−
a
j
∗
k
)
m
o
d
p
(a_i^4 - a_i*k)\bmod p \equiv (a_j^4 - a_j*k)\bmod p
(ai4−ai∗k)modp≡(aj4−aj∗k)modp
此时问题就变成了找值相等的下标对数,用map记录就可以了。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
map<ll,ll> mp;
int main()
{
ll n,p,k,x;
cin>>n>>p>>k;
for(int i=1;i<=n;i++)
{
cin>>x;
//cout<<x<<" "<<((x%p*x%p*x%p*x%p)%p-(k%p*x%p)+p)%p<<endl;
mp[((x%p*x%p*x%p*x%p)%p-(k%p*x%p)+p)%p]++;
}
map<ll,ll>::iterator it;
ll sum=0;
for(it=mp.begin();it!=mp.end();it++){
//cout<<it->first<<" "<<it->second<<endl;
sum+=((it->second)*(it->second-1)/2);
}
cout<<sum<<endl;
return 0;
}
/*(ai+aj)*(ai^2+aj^2)%p==k
(ai^2-aj^2)*(ai^2+aj^2)%p==k*(ai-aj)
(ai^4-aj^4)%p==k*ai-k*aj
(ai^4-k*ai)%p==(aj^4-k*aj)*/
感谢阅读,希望能对你产生一点用处。
标签:AC,int,题解,aj,Codeforces,long,cin,ai,572 来源: https://blog.csdn.net/qq_45750296/article/details/120672784