Codeforces Round #725(Div.3)(数论专题)
- A. Stone Game
思路:首先找到最大值 i 与最小值 j 的位置,有三种删除数的方法,从左边一直删,从右面一直删,两面各删 i 、j 个数。
const int maxn = 100005;
long long cnt[maxn][5],aa[maxn][5],a[maxn];
int n,m;
int minn,maxx;
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
rep(i,1,n)
{
cin>>a[i];
if(a[i]==1)minn = i;
if(a[i]==n)maxx = i;
}
if(minn>maxx)swap(minn,maxx);
int ans = min(minn+n-maxx+1,min(maxx,n-minn+1));
cout<<ans<<endl;
}
return 0;
}
- B. Friends and Candies
思路:算出平均值,如果不能整除,输出-1,能整出输出比平均值大的数的数量。
const int maxn = 200005;
int a[maxn];
int n,m;
int sum,aver,cnt = 0;
int main()
{
int t;
cin>>t;
while(t--)
{
sum = 0;
cnt = 0;
cin>>n;
rep(i,1,n)
{
cin>>a[i];
sum+=a[i];
}
aver = sum/n;
if(sum%n!=0)
{
cout<<"-1"<<endl;
continue;
}
else
{
rep(i,1,n)
{
if(a[i]>aver)
cnt++;
}
cout<<cnt<<endl;
}
}
return 0;
}
- C. Number of Pairs
思路:区间[ l - a[i] , r - a[i] ],查数。
int a[maxn];
int n,l,r;
ll ans;
int main()
{
int t;
cin>>t;
while(t--)
{
ans = 0;
cin>>n>>l>>r;
rep(i,1,n)
{
cin>>a[i];
}
sort(a+1,a+1+n);
rep(i,1,n)
{
ans+=upper_bound(a+1+i,a+1+n,r-a[i])-lower_bound(a+1+i,a+1+n,l-a[i]);
}
cout<<ans<<endl;
}
return 0;
}
- F. Interesting Function
思路:计算从 l 到 r 每一位的贡献求和。
ll fun(ll x)
{
ll res = 0;
while(x)res+=x,x/=10;
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
ll res = 0;
cin>>l>>r;
cout<<fun(r)-fun(l)<<endl;
}
return 0;
}
- D. Another Problem About Dividing Numbers
思路:
找到操作次数的上下界,上界是两个数质因子次数总和,下界分情况讨论:
(1)a=b
(2)gcd (a,b) = a 或者 gcd (a,b) = b
(3)ab互质。
!注意特判a==b的时候k不能为1,i<=x/i 超时,long long 会卡,用 int。
int fun(int x) //求x质因子次数之和
{
int res = 0;
for(int i = 2;i*i<=x;i++)
{
if(x%i==0)
{
int c = 0;
while(x%i==0) x/=i,c++;
res+=c;
}
}
if(x>1)res++;
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>a>>b>>k;
int up = fun(a)+fun(b);
int down = 0;
if(a==b)down = 0;
else if(a%b==0||b%a==0)down = 1;
else down = 2;
if(a==b)
{
if(k>=2 && k <= up)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else if(k >= down && k <= up)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}