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<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
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<cstdio> #include<cstring> #include<algorithm> #include<cmath> 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<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<map>
using namespace std;
int read(){
int x=0,f=1;char ch=' ';
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^'0');ch=getchar();}
return x*f;
}
const int N = 2000 + 100;
typedef long long ll;
ll a[N], b[N], sa[N], sb[N];
ll ma[N], mb[N];//每种长度的最小区间和
int main(){
int n, m; scanf("%d%d", &n, &m);
sa[0] = sb[0] = 0;
for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]), sa[i] = sa[i-1] + a[i];
for(int i = 1; i <= m; i++) scanf("%I64d", &b[i]), sb[i] = sb[i-1] + b[i];
long long x; scanf("%I64d", &x);
for(int len = 1; len <= n; len ++){
ma[len] = (1 << 30);
for (int l = 1, r = len; r <= n; l++, r++) ma[len] = min(ma[len], sa[r] - sa[l-1]);
}
for(int len = 1; len <= m; len ++){
mb[len] = (1 << 30);
for (int l = 1, r = len; r <= m; l++, r++) mb[len] = min(mb[len], sb[r] - sb[l-1]);
}
long long ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(ma[i] * mb[j] <= x) ans = max(ans, (long long)i*j);
}
}
printf("%I64d", ans);
return 0;
}
到比赛结束我连E题的面都没见到。。