Codeforces Round 929 (Div. 3)
文章目录
A. Turtle Puzzle: Rearrange and Negate
前缀和
前缀和的绝对值
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
void slove() {
int n;
cin>>n;
vector<int> a(n);
int sum=0;
for(int i=0;i<n;i++){
cin>>a[i];
sum+=abs(a[i]);
}
cout<<sum<<endl;
}
signed main() {
int T;
cin>>T;
while(T--){
slove();
}
return 0;
}
B. Turtle Math: Fast Three Task
数学
要求进行任意次操作,使得所有元素之和被3整除(也就是3的倍数)
换句话说,只要元素之和对3取模是0即可。
因为元素之和对3取模的结果只可能是 0,1,2
所以可以知道 a i a_i ai的真实值是不重要的,我们将 a i = a i m o d 3 a_i=a_imod\ 3 ai=aimod 3即可
然后求出 sum (元素和)
再让sum%3.
对sum分类讨论:当sum=0 输出0
当sum=2,只要任意一个 a i a_i ai加1,sum在小于3的情况下也会+1,输出1
当sum=1,最少的操作是1,前提是取模后的a数组内有1存在,对a排序后用find查找即可
如果存在,那么输出1
如果不存在,那么只能不断+1来达到目的,输出2
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
void slove() {
int n;
cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++)cin>>a[i];
int ans=0;
for(int i=0;i<n;i++){
a[i]%=3;
ans=ans+a[i];
}
sort(a.begin(),a.end());
if(ans%3==0){
cout<<0<<endl;
}
else{
int res=ans%3;
if(res==1){
auto pos=find(a.begin(),a.end(),1);
if(pos==a.end()){
cout<<2<<endl;
}
else{
cout<<1<<endl;
}
}
else if(res==2){
cout<<1<<endl;
}
}
}
signed main() {
int T;
cin>>T;
while(T--){
slove();
}
return 0;
}
C. Turtle Fingers: Count the Values of k
数学,枚举
1、求出 x,y的最大值
2、两重for循环,当 $ax*by<=l $ and l ( m o d ) a x ∗ b y = 0 l(mod)a^x*b^y =0 l(mod)ax∗by=0 的时候
插入set or map内
输出set的大小即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
int power(int base, int exponent) {
int result = 1;
while (exponent > 0) {
if (exponent % 2 == 1) {
result *= base;
}
base *= base;
exponent /= 2;
}
return result;
}
void slove() {
int a,b,l;
cin>>a>>b>>l;
//质因数分解
map<int,int> m;
int t=l;
int cnt=0;
while(t%a==0){
cnt++;
t/=a;
}
t=l;
int bnt=0;
while(t%b==0){
bnt++;
t/=b;
}
int ans=0;
for(int i=0;i<=cnt;i++){
for(int j=0;j<=bnt;j++){
int t1=power(a,i);
int t2=power(b,j);
if(l%(t1*t2)==0 and t1*t2<=l){
int sum=t1*t2;
m[sum]++;
}
}
}
cout<<m.size()<<endl;
}
signed main() {
int T;
cin>>T;
while(T--){
slove();
}
return 0;
}
D. Turtle Tenacity: Continual Mods
排序,数学
首先,意识到,这个数组从小到大排序。
那么最小的数不断取模,答案是不变的。
例如: 2%52 , 2%102
所以只要最小的数个数为1,那么答案必然为这个最小的数而不是0.
当最小的数不止一个的时候,我们需要用它来产生一个更小的数。
遍历整个数组a,设最小的数为a[0]
不断用 a[i]%a[0] (i>0)
如果能出现更小的数,那么最终的结果必然不为0
例如:2 2 5
5%2==1 出现了更小的数,答案为1,输出YES
如果不能出现更小的数,输出NO
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
void slove() {
int n;
cin>>n;
vector<int> a(n);
map<int,int> m;
for(int i=0;i<n;i++){
cin>>a[i];
m[a[i]]++;
}
sort(a.begin(),a.end());
int minn=a[0];
if(minn==1){
if(m[1]>1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
else{
for(int i=1;i<n;i++){
if(a[i]%minn<minn and a[i]%minn!=0){
cout<<"YES"<<endl;
return;
}
}
if(m[minn]>1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}
signed main() {
int T;
cin>>T;
while(T--){
slove();
}
return 0;
}
E. Turtle vs. Rabbit Race: Optimal Trainings
前缀和,二分,数学
由于给定了l,和u
我们需要查找 u+s[l-1]
由于前缀和是单增的,所以用lower_bound即可
找到的结果赋值为pos
现在需要比较pos和pos-1哪个更优秀
对于pos-1,
他的部分值为:sum1= sum[pos-1]-sum[l-1]
能力值:(u-sum1+1 + u)*(sum1)/2 (等差数列,首项为u,末项为u-sum1+1,项数为sum1)
对于pos
他的部分值为:sum2= (u+1) + (sum[pos]-sum[l-1]-u-1) 分为两个部分,一部分是能力增长的,一部分是能力下降的。
能力值: (正值)(1+u)*u/2 - *
(负值) (1+ sum[pos]-sum[l-1]-u-1)*(sum[pos]-sum[l-1]-u-1)/2
然后我们比较一下两者的能力值即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
void slove() {
int n;
cin>>n;
vector<int> a(n+1);
vector<int> s(n+1);
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
s[i]=s[i-1]+a[i];
}
int q;
cin>>q;
while(q--){
int l,u;
cin>>l>>u;
int pos=lower_bound(s.begin()+1,s.end(),u+s[l-1])-s.begin();
if(pos>n){
cout<<pos-1<<' ';
continue;
}
int p1=pos-1;
if(p1<l)p1=l;
int sum1= s[p1]-s[l-1];
sum1 = (u-sum1+1+u)*(sum1)/2;
int p2=pos;
int sum2=s[p2]-s[l-1];
int yu2=sum2-u-1;
sum2=(1+u)*u/2;
yu2=(1+yu2)*yu2/2;
sum2=sum2-yu2;
if(sum2>sum1)cout<<p2<<' ';
else cout<<p1<<' ';
}
cout<<endl;
}
signed main() {
int T;
cin>>T;
while(T--){
slove();
}
return 0;
}
int p2=pos;
int sum2=s[p2]-s[l-1];
int yu2=sum2-u-1;
sum2=(1+u)*u/2;
yu2=(1+yu2)*yu2/2;
sum2=sum2-yu2;
if(sum2>sum1)cout<<p2<<' ';
else cout<<p1<<' ';
}
cout<<endl;
}
signed main() {
int T;
cin>>T;
while(T–){
slove();
}
return 0;
}