7 寻找区间和
#include <stdio.h>
#include <iostream>
int main()
{
using namespace std;
int len, SUM;
int i = 0, j = 0;
int sum = 0;
int a[2010] = {0};
cin >> len >> SUM;
for (i = 0; i < len; i++)
cin >> a[i];
i = 0;
sum = a[i];
while (i <= j && j < len)
{
if (sum < SUM)
{
j++;
sum += a[j];
}
else
{
if (sum == SUM)
printf("%d %d\n", i, j);
sum -= a[i];
i++;
}
}
return 0;
}
08A:滑动窗口求最值(单调队列)
1.暴力遍历
#include <stdio.h>
#include <iostream>
int FindMin(int i, int k);
int a[2010];
int main()
{
using namespace std;
int len, k;
int sum = 0;
cin >> len >> k;
for (int i = 0; i < len; i++)
cin >> a[i];
for (int i = 0; i < len - k + 1; i++)
{
sum += FindMin(i,k);
}
cout << sum;
return 0;
}
int FindMin(int i, int k)
{
int min = i;
for (int j = i; j < i + k; j++)
{
if (a[j] <= a[min])
min = j;
}
return a[min] * a[min];
}
2.单调队列求滑动窗口最值: 虽然滑动窗口中不断有新元素加入和旧元素弹出,但是始终都有一个特点就是新元素都是从右指针r处加入的,旧元素都是从左指针l处弹出的。当一个元素如果是当前窗口的最大值,则它前面的值就不需要保存,因为只要它在窗口中,最值就不会变成其他的值,而对于它后面的比它小的元素则要保存,因为它一点弹出,最大值就要发生变化,需要保存后面的比它小的值。类似可推最小值。
————————————————
转载 --https://blog.csdn.net/weixin_41514525/article/details/113916744
#include <stdio.h>
#include <iostream>
using namespace std;
const int N = 100010;
int a[N]; int q[N];
int n, k;
void solve()
{
int hh = 0, tt = -1, sum = 0;
for (int i = 0; i < n; i++)
{
if (hh <= tt && q[hh] < i - k + 1)
hh++;
while (hh <= tt && a[q[tt]] >= a[i])
tt--;
q[++tt] = i;
if (i >= k - 1)
sum += a[q[hh]] * a[q[hh]];
}
cout << sum;
}
int main()
{
cin >> n >> k; // 为n,k赋值
for (int i = 0; i < n; i++)
cin >> a[i]; //为数组赋值
solve();
}
3.优先队列
9 区间任意最值(线段树)
遍历
#include <stdio.h>
#include <iostream>
int FindMax(int a, int b);
int a[2010];
int main()
{
using namespace std;
int len, n;
int max, min;
int sum = 0;
cin >> len >> n;
for (int i = 0; i < len; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
{
int b;
cin >> min >> max;
b = FindMax(min,max);
cout << a[b] << endl;
}
return 0;
}
int FindMax(int x, int y)
{
int j;
int max = x - 1;
for ( j = x-1; j < y; j++)
{
if (a[j] > a[max])
max = j;
}
return max;
}
10. 连续区间的最大平均值
#include <iostream>
#include <stdio.h>
int a[100001] = { 0 }, sum[10001] = { 0 }, b[10001] = { 0 };
int FindSum(int i, int f)
{
return (sum[i + f ] - sum[i])/f;
}
int main()
{
using namespace std;
int N, F, i, j = 0;
int cnt = 0;
int flag = 0;
int sum1 = 0;
sum[0] = 0;
cin >> N>>F ;
while (1)
{
int a1, s, m;
int cnt1 = 0;
cin >> a1 >> s >> m;
for (i = 0 + j; i < m + j; i++)
{
a[i] = a1 + cnt1 * s;
sum1 += a[i];
sum[i+1] = sum1;
cnt1++; // 计算s叠加次数
cnt++;
if (cnt > N)
{
flag = 1;
break;
}
}
if (flag)
break;
j = i;
}
int max = 0;
for (i = 0; i < N - F + 1; i++)
{
int t = FindSum(i, F);
if (t > max)
max = t;
}
cout << max * 1000;
return 0;
}
考试
1.给定多行,一行一个整数i,输出第i个素数(素数2是第1个素数),每个结果一行,最后一行有回车;直至输入结束
i<100010
例子
输入
1
2
5
3
输出
2
3
11
5
1.直接遍历构建素数表 (学习通运行不通过)
#include <iostream>
#define N 100100
int isprime[N];
int main()
{
using namespace std;
int cnt = 0; // 记录素数的个数
int prime = 1;
isprime[cnt++] = 2;
for (int i = 3; cnt < N; i++)
{
for (int j = 0; j < cnt; j++)
{
if (i % isprime[j] == 0)
{
prime = 0;
break;
}
prime = 1;
}
if (prime)
{
isprime[cnt++] = i;
}
}
int i;
while (cin >> i)
{
cout << isprime[i -1] << endl;
}
return 0;
}
2.埃氏筛
// 1. 创建 大小为 N 的 bool 类型数组
//2. 将 bool 数组 的值全赋值为true
//3.筛掉所有素数的倍数,剩下的就是素数;
#include <stdio.h>
#include <iostream>
#define N 1300000
#define N1 100100
bool isPrim[N];
int count1[N1];
void countPrimes() {
for (int i = 0; i < N; i++)
isPrim[i] = true;
for (int i = 2; i * i < N; i++)
if (isPrim[i])
for (int j = i * i; j < N; j += i)
isPrim[j] = false;
int cnt = 1;
for (int i = 2; i < N; i++)
if (isPrim[i]) count1[cnt++] = i;
}
int main()
{
using namespace std;
int n;
countPrimes();
while (cin >> n)
{
cout << count1[n] << endl;
}
return 0;
}
创建n阶螺旋矩阵并输出。
#include<iostream>
using namespace std;
int a[100][100];
int split(int n)
{
int cnt = 0;
do {
n /= 10;
cnt++;
} while (n);
return cnt;
}
void func(int n)
{
int i, j;
int x = 0, y = -1; //x,y表示当前数组要赋值的位置
int x_add = 0, y_add = 1; //每次赋值时,数组下标x和y的增量
int num = n, num_add_1 = n, num_add_2 = n; //num:移动方向发生变化的转变点,num_add:每次转变时num的增量
for (i = 1; i <= n * n; i++)
{
x += x_add;
y += y_add;
a[x][y] = i;
if (i == num)
{
if (y_add == 1 || y_add == -1) // row - column 横向变纵向
{
x_add = y_add - x_add;
y_add = 0;
num_add_2--;
num += num_add_2;
}
else //colunm - row 纵向变横向
{
y_add = y_add - x_add;
x_add = 0;
num_add_1--;
num += num_add_1;
}
}
}
int cnt = split(n * n);
for (i = 0; i < n; i++)
{
j = 0;
if (n <= 3)
printf("%d ", a[i][j]);
else if(n > 3 && n <=25)
printf("%2d ", a[i][j]);
else if (n > 25)
printf("%3d ", a[i][j]); // 保证第一列的最大位数与第一列的最大数相同 不产生多余空格
for (j = 1; j < n; j++)
{
switch (cnt)
{
case 1:
if (j == n - 1) // 判断是否是最后一行,如果是,不打印空格
printf("%d", a[i][j]);
else
printf("%d ", a[i][j]);
break;
case 2:
if (j == n - 1)
printf("%2d", a[i][j]);
else
printf("%2d ", a[i][j]);
break;
case 3:
if (j == n - 1)
printf("%3d", a[i][j]);
else
printf("%3d ", a[i][j]);
break;
case 4:
if (j == n - 1)
printf("%4d", a[i][j]);
else
printf("%4d ", a[i][j]);
break;
default:break;
}
}
printf("\n");
}
}
int main()
{
int n;//方阵阶数
int i; //循环变量
int b[25];
int cn = 0;
while (cin >> n)
{
func(n);
}
}
创建nm阶螺旋矩阵并输出。*
#include<iostream>
using namespace std;
int a[100][100];
void func(int n, int m)
{
int i, j;
int x = 0, y = -1; //x,y表示当前数组要赋值的位置
int x_add = 0, y_add = 1; //每次赋值时,数组下标x和y的增量
int num = m, num_add_1 = m, num_add_2 = n; //num:移动方向发生变化的转变点,num_add:每次转变时num的增量
for (i = 1; i <= n * m; i++)
{
x += x_add;
y += y_add;
a[x][y] = i;
if (i == num)
{
if (y_add == 1 || y_add == -1)
{
x_add = y_add - x_add;
y_add = 0;
num_add_2--;
num += num_add_2;
}
else
{
y_add = y_add - x_add;
x_add = 0;
num_add_1--;
num += num_add_1;
}
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("%4d", a[i][j]);
}
cout << endl;
}
}
int main()
{
int n, m; //方阵阶数
int i; //循环变量
int c[25], b[25];
int cnt = 0;
while(cin >> n >>m)
{
if (n == 0 && m == 0)
break;
c[cnt] = n; b[cnt] = m;
cnt++;
}
for (i = 0; i < cnt; i++)
{
func(c[i], b[i]);
}
}