CodeForce刷题表
Day1 题意: 从n个数中删除2个数,使剩下数的平均值不变。
思路: 删掉两个数平均值不变,所以这两个数的平均值等于n个数的平均值。
一开始想要直接for其中一个数,看看map里有没有另一个数,但是n个数的平均数×一个数可能会存在误差,导致不准确,不能准确定位。(好像不是x.5或者不是x.0就一定不存在应该也可以从这里下手解决)
既然不能用小数来解决,就转换思路:假设n个数和为sum,其中一个数是a,另一个数是b,如果满足条件( a + b ) / 2 = sum / n,那么就有 ( a + b ) * n = sum * 2 ,因此,只需要遍历一个a,另一个b通过 b * n = 2 * sum - a * n来获得即可。
代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <bits/stdc++.h> using namespace std;typedef long long ll;const int N = 1e6 +5 ;int a[N]; int main () { int t; cin>>t; while (t--) { map<ll,int > mp; ll n,sum=0 ,res=0 ; cin>>n; for (int i=1 ;i<=n;i++) { cin>>a[i]; sum+=a[i]; } for (int i=1 ;i<=n;i++) { ll tmp = 2 * sum - n * a[i]; res+=mp[n*a[i]]; mp[tmp]++; } cout<<res<<endl; } return 0 ; }
总结: 分数的问题可以尝试变成整数的问题,等式的问题可以通过转换来变成更容易解决的问题 ,尤其为了缩减时间复杂度枚举一个数来求另一个数。
题意: 在n个位置有路灯,需要照亮l长的路,最小灯照亮的半径。
思路: 遍历两个路灯间的距离,把路灯间距离除以2,取最大的一个(因为要满足所有的数),特别注意0和l的位置,特判一下即可。
代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <bits/stdc++.h> using namespace std;typedef long long ll;const int N = 1E6 +5 ; double a[N];int main () { int n,l; cin>>n>>l; double res = 0 ; for (int i=1 ;i<=n;i++) cin>>a[i]; sort (a+1 ,a+1 +n); for (int i=1 ;i<n;i++) res = max (res,(a[i+1 ]-a[i])/2 ); res = max (res,a[1 ]); res = max (res,l-a[n]); printf ("%.9f" ,res); return 0 ; }
总结: 特别注意边界的判断。
题意: 共要坐n次车,坐一次需要a元,买一次票可以坐m次,一张票b元,最少需要多少钱。
思路: 需要考虑走m时买票还是单次便宜,以及少于m时买票还是单次便宜。
代码: 1 2 3 4 5 6 7 8 9 10 11 #include <bits/stdc++.h> using namespace std;typedef long long ll;const int N = 1E6 +5 ; int main () { int n,m,a,b; cin>>n>>m>>a>>b; int tmp = min (b,(n%m)*a); cout<<min ((n/m)*b+tmp,n*a); return 0 ; }
总结: 考虑问题要全面,有‘/’和’%’两种情况的时候仔细看一点。