#include<iostream>//C语言的stdio
#include<cstdlib>//等效C语言的stdlib标准库
#include<cstring>//同理等效C语言的string标准库 //strlen(),strcmp(),strcpy(),memset(),memcpy(),
#include<cmath>//三角函数,指数函数,浮点取整函数
#include<iomanip>//C++输出小数用printf更方便,用头文件<iomanip>
#include<vector>
#include<string>
#include<algorithm>//min(1,2) nth_element min_element swap(a[0],a[1]),reserve(a.begin(),a.end() ) ,unique(a.begin() ,a.end())
//nth_element(a.begin(), a.begin() + n,a.end()); 时间复杂度O(n)
// 把数组中第n小的数放在第n个位置上(过程中会排序),类似快排O(n),并且保证左边的数比它小,右边的数比它大
//min_element(a.begin(),a.end());//快速找最小元素
//unique要在sort后再用 ,元素值不重复,获得新数组 ,新数组长度用 = unique(a.begin() ,a.end()) - a.begin()
#include<stack>
#include<queue>
#include<map>
//pair<string,int> pr {"小明",180};//相关联两个变量,
//map<string,int> student student["小明"] =180 ; //任意当下标
#include<unordered_map>
#include<unordered_set>
//#include<bits/stdc++.h>//包含一切头文件,但Visual没有,可自创
using namespace std;//C++标准库前加std:: ,加此行就不用了
//**但是起名的时候容易与标准库冲突 (prev,next, sort,count)都不能取
/*endl 等于 \n */
/*竞赛细节: 1s 约为 le8
G++用double时 ,用%f
注意多组用例的EOF、初始化的常数时间也得估计好
数据范围和运算结构均在le9以内
const int INF = 0x3f3f3f;//表示无穷大
memset(arr,INF,sizeof(arr))来令数组初始化为无穷大 ,把数组的每一个地方都变成了无穷大
*/
const int INF = 0x3f3f3f;//表示无穷大
vector<int>list1; //超级数组,既可以项C语言一样用数组下标表示,也可以像链表一样动态改变长度
vector<int>arr1(100);
int arr2[100];
vector<int>::iterator p1; //STL中的指针被称为迭代器"iterator"
int* p2;
int cmp(int a, int b) {
return a > b;
}
void class1() {//基础认识
int a[] = { 1,3,5,4,2 };
string cstring;
cstring.size();//O(n) 与C语言cstring唯一的不一样
cout << "helloworld";
//cin.get();
getline(cin, cstring); //可以这样赋值一行
list1.push_back(1);//scanf("%d",&list[i]); 键入赋值
list1.push_back(2);
list1.push_back(3);
for (int i = 0; i < arr1.size(); i++) {//arr1.size()的大小,占空间字节 arr1.begin(),arr1.size()必须具有int*类型才可使用
int a;
cin >> a;
arr1.push_back(a);//对象.push_back()函数 在最后输入
//list.push_back(a);
printf("%d\n", arr1[i]);//最开始未赋值,初始全为0
//printf("%d\n", list[i]);
}
min_element(a, a + 5);//可在未排序数组中找最小元素 O(n)
sort(a, a + 5);//O(nlgn), sort(a.begin(), a.end() )//排的范围
//和C语言的qsort一样,可以自定义sort函数
sort(arr1.begin(), arr1.end(), cmp);//可得到降序(大到小)
int newLength = unique(arr1.begin(), arr1.end() ) - arr1.begin();//线段树与树状数组详细讲此函数
//int a = lower_bound(arr1.begin(), arr1.end(), 2) - arr1.begin();//在数组中的位置
//一个排好序的数组中寻找一个数,是否存在,返回插入位置或存在位置
//lower_bound返回第一个插入位置的指针 upper_bound返回最后一个插入位置的指针
}
//模拟 把程序按步骤写出 ,
//例题一 约瑟夫环
//用循环链表 或 数组 p = (p + m - 1)%n
void Joseph(int n,int m)
{
int a[100] , k = 0, p = 0;
for (int i = 0; i < n; i++)
a[i] = i + 1;
while (n > 1)
{
p = (p + m - 1) % n;
cout << "第" << ++k << "个出圈的是:" << a[p] << endl;
for (int j = p + 1; j < n; j++)
{
a[j - 1] = a[j];
}
n--;
if (p == n)
{
p = 0;
}
}
cout << "最后剩下的是:" << a[p] << endl; // int a[100] = { 0 }
}
//例题二 Online judge//模拟测试机(题号HDU-1073 )
//把题目给的输入的特殊符号先去掉, '\n' '\t 和'',再判断是否完全匹配,不是则一定WA(答案错误),
//如果匹配了,去掉之前不完全匹配则PE(格式错误) ,,两组数据都匹配,则是AC
/*例题三 False Coin (POJ-1029)
*/
//暴力brute force
/*即枚举,时间复杂度要估算好
*/
//例题一 Sn = 1 + 1/2 + 1/3 +...+ 1/n ,计算第n项时大于整数k, k范围(1-15)
int query(int k) {
double sum = 0;
for (int i = 1;; i++)
{
sum += 1.0 / i;
if (sum > k)
{
return i;
}
}
}
//例题二 百钱买鸡问题
/*
解法一:forforfor 枚举x,y,z
解法二:forfor 枚举x,y ,z = x - y,求出z
解法三:for 枚举x ,解出y,z * 暴力需要优化!*
*/
void f3() {
for (int x = 0; x <= 25; x++) {
if ((200 - 8 * x) % 14 == 0 && (1200 - 6 * x) % 14 == 0) {//取刚好余数为0
cout << x << " " << (200 - 8 * x) / 14 << " " << (1200 - 6 * x) / 14 << endl;
}
}
}
void class2() {//模拟&暴力
//Joseph(7, 3);
//cout<< query(10) <<endl;
f3();
}
/*输入整数n, 输出所有形如abcde/fghij=n的表达式 【 用0-9的数字随机排序(0可以在前) 如13579/02468 】
可以直接枚举10! = 300多万,可以接受,但没必要
只需枚举fghij,可以算出abcde = fghij*n,减少到1万次以内
*/
//在如12345字符串(长度5到20)按照顺序插入 '+' ,'-' ,'*' ,'/',求最大的计算结果
/*直接暴力可能20^4超时,
* 把表达式固定,a+b-c*d/e;我们希望a、b、e大些,减去的c、d小一些
* 给c和d各一位,给e一位或两位,a和b的一个拿一位,另一个拿光
*
* void Operation() {}
* */
/*白学串
给定一个n个数的数字序列,每个数不超过le9,有q次询问,每次询问的一个区间是否存在三个数可以组成一个三角形,输出YES或NO (1<=n,q<=le5)
不能构成三角形的充要条件是拍完序后任意三个相邻的数构不成三角形,
不能构成三角形的极限情况就是斐波那契数列 1,1,2,3,5,8,13,21.......
而斐波那契数列增长很快40项就达到了le9,所以当区间长度超过40,输出YES,否则排序后判断或者直接暴力
*/
//简单数据结构入门
/*①前缀和
两次异或抵消,
极速讲解例题,非常数学
②链表
邻接表、栈与队列(判断括号匹配、!单调栈!、)
队列用BFS求迷宫,1->2 ...->n,用递归回来的时候输出路径
优先队列,按优先级
例:两个排好序的序列A、B(长度为n,le5)求前n大的A[i]+B[j]
使用优先队列,一开始将A序列中最大的与B中的元素依次相加存进队列,每次弹出的最大的和组合(Ai,Bi,Ai+Bi)再新加入(Ai+1,Bj,Ai+1,Bj) 没懂。。。
void class3() {}
*/
/*字符串
string支持 + 或+= ,也可以用append
Hash(i)递归求串S的后缀i的哈希值 进制转换 return Hash(i+1)*进制 +s(i)字符串的第几位
例题数组重复元素删除,保留第一次出现的 sort,平衡树调用库,
......字典树,难度偏大了目前 ,且课不完整
void class4() {}
*/
/*贪心与排序
数学水平。。。
sort(First_point,First_point+n,cmp)
void class5() {}
*/
/*动态规划
解决状态和转移
例1:数字三角形走到最底层的路径最小值
考虑哪些前状态转移到这个状态
状态明确两点:初始状态,答案在哪里取
例二:最长上升子序列(LIS)
*背包问题九讲...
void class6() {}
*/
/*二分三分快速幂矩阵快速幂
二分法(begin,end,value) 前提单调!
具有单调性/连续性的问题的查找
例题:n个牛栏位于X1...Xn ,插入m头牛使得相邻牛之间的距离最大 (二分答案的标志最大值最小或最小值最大)
遍历取一段距离,若插入的完则合理可行,反之不行
例题:有n*m乘法表,把n*m个数从大到小排序,求第k个数
把每行每列的数小于x计数与k比较大小
*三分法 凸性函数
快速幂
求a^b mod p
a^2i = a^i*a^i ,快速求出a的平方,四次方,八次方...
将b做二进制拆分
a^b = a^b1 + a^b2 + a^b3... O(logb)
*/
int quickpow(int a,int p,int mod) { //a,b,p
int ans = 1, a = a % mod;
while (p) //当p != 0时
{
if (p & 1) ans = (ans * a) % mod; //p & 1 !=0 即p时奇数,把答案乘底数模
p >>= 1; // p/2
a = (a * a) % mod; //a^0 a^2 a^4
}
return ans;
}
/*矩阵乘法快速幂
将快速幂中的底数换成矩阵, 线性递推式
例:求斐波那契数列的第n项,利用系数矩阵
*/
void class7() {
}
//后还剩DFS、拓扑排序,树 认为无代码且需要有较好的基础才适合听
//暂告一段落
int main() {
class2();
return 0;
}
c++版ACM技巧学习
于 2022-02-09 13:31:02 首次发布