A:Stone Game
题意:
n块石头,排成一行,每块石头拥有不同的重量。
你的任务就是:摧毁当中最轻和最重的那两块石头
摧毁规则:
只能摧毁最左面和最右边的石头。
注意:被摧毁的石头就代表消失。
问最少摧毁几块石头可完成任务。
题解:
找出重量最大和最小的下标。
分三种情况考虑:
1.要么从左到右进行摧毁。
2.要么从右至左进行摧毁。
3.要么两边进行摧毁。
三种情况取最小即为答案。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1110];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int maxx=0,minn=1111,xx=1,nn=1;
for(int i=1;i<=n;i++)
{
if(maxx<a[i])
{
maxx=a[i];
xx=i;
}
if(minn>a[i])
{
minn=a[i];
nn=i;
}
}
if(xx>nn) swap(xx,nn);
int mind=9999;
mind=min(mind,nn);
mind=min(mind,n+1-xx);
mind=min(mind,n+1-xx);
mind=min(mind,xx+n+1-nn);
printf("%d\n",mind);
}
return 0;
}
B:Friends and Candies
题意:
Polycarp有n个朋友,
初始每个朋友被分配ai个糖果,
但Polycarp觉得每个朋友的糖果数量应该相等,
因此Polycarp想重新分配一次。
他可以挑选任意k个朋友,然后把他们的糖果集中在一起,
这时候,Polycarp会拿着这些糖果进行重新分配。
若分配不能一致,输出-1
若能,输出k的最小值。
题解:
水题。只要找出比平均值大的人有几个即为答案。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+1100;
int a[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
ll sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
int ave=sum/n;
if(ave*n!=sum)
printf("-1\n");
else
{
sort(a+1,a+1+n);
int p=upper_bound(a+1,a+1+n,ave)-a;
printf("%d\n",n-p+1);
}
}
return 0;
}
C题: Number of Pairs
题意:
t组样例。
给出3个整数n,l,r
接着给出长度为n的序列.
求该序列有多少对满足下列不等式。
满足:l <= a[i]+a[j] <= r.(1 <= i < j <= n)
题解:
举个例子来说:
5 5 8
5 1 2 4 3
可知:在 i < j 的情况下,一共可以匹配 ( n - 1 ) * n / 2对
即
(5,1),(5,2),(5,4),(5,3)
(1,2),(1,4),(1,3)
(2,4),(2,3)
接着对上述进行调整,保证括号内左边<右边
这不会影响结果。
(1,5),(2,5),(4,5),(3,5)
(1,2),(1,4),(1,3)
(2,4),(2,3)
(3,4)
再调整:
(1,2),(1,3),(1,4),(1,5)
(2,3),(2,4),(2,5)
(3,4),(3,5)
(4,5)
因此排序不会影响结果,还可以利用二分。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=2e5+1100;
ll a[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll n,l,r;
scanf("%lld %lld %lld",&n,&l,&r);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+1+n);
ll ans=0;
for(int i=1;i<=n;i++)
{
int p1=lower_bound(a+i+1,a+1+n,l-a[i])-a;
int p2=upper_bound(a+i+1,a+1+n,r-a[i])-a;
ans+=(p2-p1);
}
printf("%lld\n",ans);
}
return 0;
}
D:Another Problem About Dividing Numbers
待补。
F:Interesting Function
题意:
给你L和R,让L一直加1,直至等于R。
计算在这期间:前一个数与后一个数各位不同数量 的累加之和。
题解:
举个例子:
样例:1 100
答案:110
可看做:
001
100
在001变化到100时,
只看个位上数字的变化:次数=100-1=99次。
只看十位上数字的变化:次数=10-0=10次,即1,2,3,4,5,6,7,8,9,0.
…
各位上的数字都遵循上述规律。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll L,R,ans;
void solve()
{
while(L!=0||R!=0)
{
ans+=(R-L);
L/=10;
R/=10;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld %lld",&L,&R);
ans=0;
solve();
printf("%lld\n",ans);
}
return 0;
}