Codeforces Round #513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2)
- Solved : 2 out of 8...
- Rank : 2730 unrated
- A. Phone Numbers
- 难度:普及组。
- 模拟即可。。每个电话号码占用一个'8'和其他10个数码。
- Summary : 简单题不要浪费过多时间,要提高做题的精度。
#include
#include
#include
#include
using namespace std;
const int N = 100 + 10;
int cnt =0;
int main(){
int n; scanf("%d", &n);
for(int i=1;i<=n;i++) {
char ch;
cin>>ch;
if(ch == '8') cnt++;
}
int ans=0;
while(n){
if(cnt&&n>=11) cnt--,n-=11,ans++;
else break;
}
printf("%d",ans);
return 0;
}
- B. Maximum Sum of Digits
- 难度: 提高组D1T1?
- 贪心
- 对于小于10的数字,a = n, b = 0
- 对于大于10的数字,我们选择用尽量多的⑨去凑a直到再凑a就会大于n,然后a的最高位就是n的最高位-1,这样就构造出a了。
- 然后b = n - a。
- Tips:
- pow()函数什么的。。。还是自己写个long long的快速幂吧。。。
- 样例感人。。。还好打了个表找了找规律。。。
- Summary :
- 结论题 or 贪心题 一定要打个表写对拍检查一下结论的正确性。
- 为防止中间量爆long long的情况,在大数据的题目中,能开long long尽量开long long。
#include
#include #include #include using namespace std; long long cal(long long a){ long long ans=0; while(a){ long long dig=a%10; ans+=dig; a/=10; } return ans; } long long fpow(long long a,long long b){ long long ans=1; for(;b;b>>=1){ if(b&1) ans*=a; a*=a; } return ans; } int main(){ long long n; scanf("%I64d", &n); long long ans; long long a ; if(n<10) a= n; else { a = 0;long long cnt=0; while(a<=n) a=a*10+9,cnt++; if(a>n) a/=10,cnt--; long long top;long long x=n; while(x){ if(x/10>0)top=x/10; x/=10; } top--; long long pw=fpow(10,cnt); a=(long long)top*pw+a; } long long b ; if(n<10) b=0; else { b = n-a; } ans = cal(a) + cal(b); printf("%I64d",ans); return 0; }
- C.Maximum Subrectangle
- 难度:D1T2
- 前缀和 + 枚举。。。
- 我们将\(c_{i,j}=\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2}a_i*b_j\)化成\(c_{i,j}=\sum_{i=x_1}^{x_2}a_i\sum_{j=y_1}^{y_2}b_j=(suma[x_2]-suma[x_1-1])*(sumb[y_2]-sumb[y_1-1])\)。即c可以由a,b的前缀和中各一个区间相乘得到。
- 由于最终矩形元素和\(\leq x\)即可,所以我们可以预处理出\(suma\)中各长度的和最小的区间and\(sumb\)中各长度的和的最小的区间,然后\(O(n^2)\)枚举a,b各自的长度即可。。。
- Summary :
- 要有前缀和优化的意识。。
- 别把题目想得太难。(当然也别too naive。。
#include
#include
#include
#include
#include
#include
#include
到比赛结束我连E题的面都没见到。。