2021-10-17
每周学习总结
1,比如m中需要减几个a和b才能小于零,ab交替减。这种题,不要用循环,因为数据量和数据大小不允许,所以直接用除法。
2,递增即可不用数值对应下标。
3,前后各n个, i<=n,i>m-n
4,题目说i-j>=k 如果一共有n个元素,那也可以写成n-k–k个。
5,atof需要调用<stdlib.h>头文件,类似的还有atoi,atol,itoa,ftoa。atof会跳过前面的空格符直到遇见正负号或者是数字开始,最后遇到不是数组或者是\0结束。
1,B. Hemose Shopping-Round #746 (Div. 2)
这题虽然是b题,但是思路和代码还是需要一定的能力的。(;`O´)o
思路,刚开始没有点思路,尝试着分析5 3 5 1 2 3 4这个例子。排列出16种组合,浪费了很长时间。之后想既然只能和i-j距离外的进行交换,也就可以想到是数组的前i个和后i个,思路也就是判断在j+1–n-j之间是否是递增的,然后判断剩余的2*j个元素是否是数组的前j个和后j个。这个思路难在如何判断是否是前后j个,1,结果体对每个元素都标上下标,然后排序,判断下标是否在范围内。但是这种方法是错误的,因为可能第j和第j+1个元素的值是相同的。2,建立另外一个数组,只对一个数组进行排序,对没有排序的数组的相应元素进行判断。
结果也是错的,至今不懂如何错的。(๑•̌.•̑๑)ˀ̣ˀ̣
正确思路,两个数组,第一个数组排列,然后求中间范围内的元素是否和对应的元素是否相等即可。
有点难,还有想麻烦了(=_=)
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int i1,i2,i3,i4,i5;
int a[100010],b[100010];
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n>>m;
i2=n-m;
if(i2<0) i2=0;
int flag=1;
for(i1=1;i1<=n;i1++)
{
cin >> a[i1];
b[i1]=a[i1];
}
sort(a+1,a+1+n);
for(i1=1;i1<=n;i1++)
if(i1>i2&&i1<=m) if(a[i1]!=b[i1]) {flag=0;break;}
if(flag==0) cout << "NO" << endl;
else cout << "YES" << endl;
}
return 0;
}
2,逆波兰表达式–前缀表达式。
重点是在第二种
1,数据结构上会把求解后缀表达式的方法应用到后缀,也就是把前缀表达式从后向前进行计算,而且是把数字压到栈里去。
2,可以采用递归的方法也就是将问题简化成小部分,或者是说把运算符之后的两个数字看成一个整体,这样即容易想代码又简单。(调用了将字符串转换为浮点数的函数)
(1)这种方法运用到了cin>>不可以输入空格
(2)采用atof减化代码。
#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
double f()
{
string x;
cin>>x;
if(x=="+") return f()+f();
else if(x=="-") return f()-f();
else if(x=="*") return f()*f();
else if(x=="/") return f()/f();
else return (atof(&x[0]));
}
int main()
{
printf("%f\n",f());
return 0;
}