成绩:
配置:
可能与实际有些出入
题目:
第一题:
代码思路:
一道模拟题,按照公式计算出sum+=pow(2,i),判断sum>H,输出
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
long long h,ans = 1; cin >> h;
for(int i = 1; i <= (h+100); i++){
ans += pow(2,i);
if(ans > h){
cout << (i+1) << endl;
break;
}
}
return 0;
}
第二题:
代码思路:
前缀和的经典题目。
输入,求前缀和,枚举K(正方形边长)从1-max(m,n),从开始枚举正方形左上端点如果等于k*K说明其完全由1的数字组成,最后输出最大的K。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 250;
int a[N][N],s[N][N];
int main(){
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
int n,m; cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
s[i][j] = s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
int maxn = 0;
for(int k = 1; k <= min(n,m); k++){
bool flag2 = 1;
for(int i = 1; i <= n-k+1; i++){
bool flag = 0;
for(int j = 1; j <= m-k+1; j++){
if((s[i+k-1][j+k-1]-s[i+k-1][j-1]-s[i-1][j+k-1]+s[i-1][j-1]) == k*k){
maxn = max(maxn,k);
flag = 1;
break;
}
}
if(flag) break;
}
}
cout << maxn << endl;
return 0;
}
第三题:
代码思路:
差分题目。数据范围较大如果暴力会超时,所以考虑差分。
创建差分数组a储存数字,如果在l-r区间内+1,则a[l]+=1,a[r+1]-=1,最后进行前缀和操作,排序,输出中位数。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
long long a[N];
int main(){
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
int n,k; cin >> n >> k;
for(int i = 1; i <= k; i++){
int l,r; cin >> l >> r;
a[l] += 1; a[r+1] -= 1;
}
for(int i = 1; i <= n; i++){
a[i] = a[i-1]+a[i];
}
sort(a+1,a+n+1);
cout << a[n/2+1] << endl;
return 0;
}
第四题:
代码思路:
二分答案经典习题。错误原因:check函数没有写对。
二分选择间隔距离,如果按照此间隔不可以放完所有牛,在l-mid-1区间里继续二分。
否则,在mid-r的区间里二分。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], n, c;
bool check(int mid) {
int res = 1, prev = a[1];
for (int i = 2; i <= n; i++) {
if (a[i] - prev >= mid) {
res++;
prev = a[i];
}
}
return res >= c;
}
int main() {
freopen("d.in", "r", stdin);
freopen("d.out", "w", stdout);
cin >> n >> c;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
int l = 0, r = a[n] - a[1];
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
return 0;
}
第五题:
代码思路:
错误思路:排序+暴力.优化(遇到a[j]的数不合法就结束)。(70-80分)
正确思路,二分查找右端点,r-l之间就是a[i]位上的搭配。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
int n, s;
int a[N];
int main() {
freopen("e.in", "r", stdin);
freopen("e.out", "w", stdout);
cin >> n >> s;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
int ans = 0;
for (int i = 1; i + 1 <= n && a[i] < s; i++) {
int l = i + 1, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (a[mid] <= s - a[i]) l = mid;
else r = mid - 1;
}
if (a[l] <= s - a[i]) ans += l - i;
}
cout << ans << endl;
return 0;
}
总结:
此次题目并不算难但是成绩却不是理想,所以要继续努力,计划每周做一套csp-j/s的初赛题
,和3道附加题。