算法学习
有一段时间没集中做题了,Debug慢了好多, 数组范围注意
A - 高精度加减法
高精度加减,多次输入
https://vjudge.net/contest/417084#problem/A
题意
第一行输入表示有几(t)组数据
下面t行, 为xxxxx (+或-) xxxxxx形式,其中xxxxxx(数字)最多有500位
输出 结果
几个小点
1.将输入转化为数组,符号,数组
先整体读入,再分开录入,转化为数字
[注意] 数字要把个位存在开头,方便进位,特别是数字长度不同的时候~~
2.加法,
这个还好说, 记得注意会进位, 需另开sum记录a[i], c[i]十位
3.减法***
- 先找大的数是哪个(这里为check函数鉴定), 如果前面的数小,先输出负号,但不管怎样,记得减法时把大数放前面
- a-c<0时, 先给a加个油+10, 特殊情况完后 d=a-c
- 输出,前面的零省略,最后的不能省
此题最后的最后
每次开始数组默认都为0 ! ! !
这回全局变量可不方便了, 后边a[N] = {0} 就行了
#include <iostream>
using namespace std;
const int N = 510;
int n;
void change(int a[], int n)
{
for(int j = 1; j <= n / 2; j ++)
swap(a[j], a[n - j + 1]);
return;
}
int check(int n1, int n2, int a[], int c[])
{
if(n1 != n2)
return n1 - n2;
else
for(int i = n1; i > 0; i --)
if(a[i] != c[i])
return a[i] - c[i];
return 1;
}
void jia(int a[], int c[])
{
int d[N];
int i, sum = 0;
for(i = 1; i <= n; i ++)
{
sum += a[i] + c[i];
d[i] = sum % 10;
sum /= 10;
}
if(sum > 0)
n ++, d[i] = sum;
for(i = n; i >= 1; i --)
printf("%d" , d[i]);
printf("\n");
return;
}
void jian(int a1[], int c1[])
{
int d[N];
for(int i = 1; i <= n; i ++)
{
if(a1[i] - c1[i] < 0)
a1[i] += 10, a1[i + 1] --;
d[i] = a1[i] - c1[i];
}
for(int i = n, t = 0; i > 1; i --)//前边若为零,则不输出
if(d[i] == 0 && t == 0)
continue;
else
printf("%d", d[i]), t = 1;
printf("%d\n", d[1]);//无论如何,最后的0,必须输出
return;
}
int main()
{
int t;
scanf("%d", &t);
getchar();
while(t --)
{
char q[2 * N], b;
int i, j, n1, n2, a[N] = {0}, c[N] = {0};
gets(q);
for(i = 0; q[i] != '+' && q[i] != '-'; i ++)//a
a[i + 1] = q[i] - '0';
n1 = i;
b = q[i ++];//b
for(j = 0; q[i] != '\0'; i ++, j ++)//c
c[j + 1] = q[i] - '0';
n2 = i - n1 - 1;
n = n1 > n2? n1: n2;//最长的数字长度
change(a, n1);//转为数字倒序,方便计算
change(c, n2);
if(b == '+')
jia(a, c);
else
if(check(n1, n2, a, c) < 0)
printf("-"), jian(c, a);
else
jian(a, c);
}
return 0;
}
B - Subsequence
前缀和,双指针算法
https://vjudge.net/contest/417084#problem/B
题意
第一行, 输入样例个数t
t 组,第一行:数字个数n 数m
找到连续数之和>m,中最小连续数字个数, 输出
解析
另存数组为前i 个数字和, ------> 防超时
找符合条件(此板子,转于acwing)
(while里, 如果所指元素可能为同一个时,则 j<= i)
for(i = 0, j = 0;i < n; i ++)
{
while(j < i && check(i, j)) j ++;
//每道题具体逻辑
}
#include <iostream>
#include <stdio.h>
using namespace std;
const int N = 1e5 + 10;
const int inf = 1e8 + 50;
int main()
{
int t, n, m;
scanf("%d", &t);
while(t --)
{
int a[N], he[N] = {0};
scanf("%d%d", &n, &m);
scanf("%d", &a[0]);
for(int i = 1; i < n; i ++)
{
scanf("%d", &a[i]);
he[i] = he[i - 1] + a[i];
}
if(he[n - 1] < m)
{
printf("0\n");
continue;
}
int res = inf;//最大值
for(int i = 0, j = 0; i < n; i ++)
{
while(j <= i && he[i] - he[j] + a[j] >= m)//具体题目具体分析
{
res = min(res, i - j + 1);// i~j包括两边的元素个数
j ++;
}
}
printf("%d\n", res);
}
return 0;
}