题目结构
项目 | 题型 | 分值 | 题型 |
---|
第一题 | 结果填空 | 5 | 第几天(日期处理) | 第二题 | 结果填空 | 5 | 明码(位运算) | 第三题 | 结果填空 | 10 | 乘积尾零(数学+取位数) | 第四题 | 结果填空 | 10 | 测试次数(DP) | 第五题 | 结果填空 | 15 | 递增三元组(双指针) | 第六题 | 程序设计 | 15 | 快速排序 | 第七题 | 程序设计 | 20 | 螺旋曲线(找规律) | 第八题 | 程序设计 | 20 | 日志统计(结构体) | 第九题 | 程序设计 | 25 | 全球变暖(BFS) | 第十题 | 程序设计 | 25 | 乘积最大 |
第一题 第几天
- excel解决
- 手算
答案:125
第二题 明码
x>>j&1 :判断x的二进制排列中,第j 位是否为1
#include <iostream>
using namespace std;
int main(){
for(int i=0;i<320;i++){
int x;
cin>>x;
for(int j=7;j>=0;j--){
if(x>>j&1) cout<<"1";
else cout<<" ";
}
if(i%2==1) cout<<endl;
}
return 0;
}
10个汉字是 : 九的九次方等于多少? 答案: 387420489 注意: 思路: 首先要明白 , 计算机存储的都是 二进制,正数就是二进制表示即原码, 负数是对其 正数原码的 各位取反末尾加一 即补码, 计算机中存储的本身就是二进制,不用特意去求 所以直接 用 n&1 就可以直接得到其二进制数字。
x >>= 1 等同于 x = x/2; 这是位运算, >>左移运算,<< 右移运算 x >> n 等同于 x / (2^n) x << n 等同于 x * (2^n) 当然了,要注意类型所占内存的大小,以防溢出
第三题 乘积尾零
#include <iostream>
using namespace std;
int main()
{
int num2=0,num5=0;
for(int i=0;i<100;i++){
int x;
cin>>x;
while(x%2==0){
num2++;
x/=2;
}
while(x%5==0){
num5++;
x/=5;
}
}
cout<<(num2>num5?num5:num2)<<endl;
}
第四题 测试次数
第五题 递增三元组
题解一:三重循环(超时)
#include <iostream>
#define MAX 1000005
using namespace std;
typedef long long ll;
ll A[MAX],B[MAX],C[MAX];
ll N,cnt;
int main(){
cin>>N;
for(int i=0;i<N;i++){
cin>>A[i];
}for(int i=0;i<N;i++){
cin>>B[i];
}for(int i=0;i<N;i++){
cin>>C[i];
}
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
if(A[i]<B[j]&&B[j]<C[k]){
cnt++;
}
}
}
}
cout<<cnt<<endl;
return 0;
}
题解二:双指针法
时间复杂度:N logN
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100010;
int a[N],b[N],c[N];
int n,p,q;
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
for(int i=0;i<n;i++) cin>>c[i];
sort(a,a+n);
sort(b,b+n);
sort(c,c+n);
long long ans=0;
for(int i=0;i<n;i++){
while(p<n&&a[p]<b[i]) p++;
while(q<n&&c[q]<=b[i])q++;
ans+=(long long)p*(n-q);
}
cout<<ans<<endl;
return 0;
}
若出现比较大小问题,最好先进行排序,因为三重循环会超时所以使用双指针方法。 遍历B 数组,在A 数组中找到p 个比b1小的数,在C 数组中找到q 个小于等于b1的数,那么比b1 大的数的个数为n-q 最后结果即为p*(n-q) 然后随着遍历B数组累加。
第六题 快速排序
#include <stdio.h>
#include<cstdlib>
int quick_select(int a[], int l, int r, int k) {
int p = rand() % (r - l + 1) + l;
int x = a[p];
{int t = a[p]; a[p] = a[r]; a[r] = t;}
int i = l, j = r;
while(i < j) {
while(i < j && a[i] < x) i++;
if(i < j) {
a[j] = a[i];
j--;
}
while(i < j && a[j] > x) j--;
if(i < j) {
a[i] = a[j];
i++;
}
}
a[i] = x;
p = i;
if(i - l + 1 == k) return a[i];
if(i - l + 1 < k) return quick_select(_________);
else return quick_select(a, l, i - 1, k);
}
int main()
{
int a[] = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12};
printf("%d\n", quick_select(a, 0, 14, 5));
return 0;
}
答案:a, p+1, r, k-(i-l+1) 或者 a, p, r, k-i+l
首先看参数要求: 第一个参数a:数组 第二个参数l:左指针 第三个参数r:优指针 第四个参数k:寻找第k个元素 l~i区间里为比枢纽小的数,共l-i+1 个元素 i+1~r区间都是比枢纽大的元素 如果l-i+1 大于k,还是在l~i-1区间找第k个元素 如果l-i+1 小于k,在i+1~r区间找元素,那么是找第几个元素呢?应为k-(i-l+1) 个元素
第七题 螺旋曲线
参照链接 https://blog.csdn.net/qq799028706/article/details/84312062
#include <iostream>
#include <algorithm>
using namespace std;
long long x,y,sn,n,sum;
long long px,py,d1,d2;
int main()
{
cin>>x>>y;
n=max(abs(x),abs(y));
sn=4*(n-1)*n;
sum=sum+sn;
px=-n,py=-n;
d1=x-px,d2=y-py;
if(y>x){
sum+=(d1+d2);
}else{
sum+=(8*n-d1-d2);
}
cout<<sum<<endl;
}
第八题 日志统计
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int > PII;
const int N = 100010;
PII a[N];
int cnt[N];
bool st[N];
int main()
{
int n, d, k;
cin >> n >> d >> k;
for (int i = 0; i < n; i ++) scanf("%d%d", &a[i].x, &a[i].y);
sort(a, a + n);
for (int i = 0, j = 0; i < n; i ++)
{
cnt[a[i].y] ++;
while(a[i].x - a[j].x >= d)
{
cnt[a[j].y] --;
j ++;
}
if(cnt[a[i].y] >= k) st[a[i].y] = true;
}
for (int i = 0; i < N; i ++)
if(st[i]) printf("%d\n", i);
}
第九题 全球变暖
|