前言警告:
1、注意数据的边界,数组不能越界!
2、 时间复杂度
3、开long long
4、注意输出的四舍五入
printf("%d %.0f\n",k,sum*1.0/k);//double类型输出会自动四舍五入;
5、让Dev C++支持C++11
先在dev的【工具】里找到【编译选项】
打勾输入:
-std=c++11
C++语法
输出随机数
#include<stdlib.h>
#include<time.h>int main()
{int X=17;srand(time(NULL));printf("%d",rand()%X);//输出一个0~X-1的随机整数。return 0;
}
print一堆
printf(R"()");
printf(R"( ,----, ,--, ____,----.. .' .`| ,--.'| ,---, ,----.. ,' , `./ / \ .' .' ; ,--, | : ,--, ' .' \ / / \ ,-+-,.' _ |
| : : ,---, ' .',---.'| : ' ,'_ /| / ; '. | : : ,-+-. ; , ||
. | ;. / | : ./ | | : _' | .--. | | : : : \ . | ;. / ,--.'|' | ;|
. ; /--` ; | .' / : : |.' |,'_ /| : . | : | /\ \ . ; /--` | | ,', | ':
; | ; __ `---' / ; | ' ' ; :| ' | | . . | : ' ;. : ; | ; | | / | | ||
| : |.' .' / ; / ' | .'. || | ' | | | | | ;/ \ \| : | ' | : | : |,
. | '_.' : ; / /--, | | : | ': | | : ' ; ' : | \ \ ,'. | '___ ; . | ; |--'
' ; : \ | / / / .`| ' : | : ;| ; ' | | ' | | ' '--' ' ; : .'|| : | | ,
' | '/ .'./__; : | | ' ,/ : | : ; ; | | : : ' | '/ :| : ' |/
| : / | : .' ; : ;--' ' : `--' \| | ,' | : / ; | |`-'\ \ .' ; | .' | ,/ : , .-./`--'' \ \ .' | ;/`---` `---' '---' `--`----' `---` '---')");
\n\
打印转行的格式
#include<iostream>
using namespace std;
int main(){cout<<"4396 = 28 x 157\n5346 = 18 x 297\n\
5346 = 27 x 198\n5796 = 12 x 483\n\
5796 = 42 x 138\n\
6952 = 4 x 1738\n\
7254 = 39 x 186\n\
7632 = 48 x 159\n\
7852 = 4 x 1963\n";
}
output:
4396 = 28 x 157
5346 = 18 x 297
5346 = 27 x 198
5796 = 12 x 483
5796 = 42 x 138
6952 = 4 x 1738
7254 = 39 x 186
7632 = 48 x 159
7852 = 4 x 1963
\\n ,\"
需要输出特殊符号,则在前面加 ' \ '
printf("printf(\"Hello world!\\n\");\n");
printf("cout << \"Hello world!\" << endl;");
output:
printf("Hello world!\n");
cout << "Hello world!" << endl;
%% ,%.nf
%%输出”%“ ,%.nf精确到小数点后n位
(double类型 %.lf )
printf("%.3f%%",m);
output:
2.684%
getline(cin,a)与getchar()
输入带空格的字符串
#include<cstring>
string a;
getline(cin,a);//默认遇到/n后截至getline(cin, b,'E');//设置遇到字符E后停止
当前面用了cin,需要用getchar()接收\n,才能用getline
cin>>n;
getchar();//必须要,否则getline会接收\ngetline(cin,str);
在输入结束后,还要输入字符则中间必须跟getchar()吃掉回车
scanf("%c %d",&c,&n);getchar(); //吞换行回车
scanf("%c %d",&c,&n);getchar();
cin>>c;
while(cin>>a>>b)
用于输入多组数据
unsigned long long n
遇到问题: 一个数在64位二进制补码表示下,一共有多少个1?时用
‘long long’ 只有32位
%x和%o
输出十六进制数 和八进制
int a=11,b=1;printf("%x",a+b);//十六进制printf("%o",a+b);//八进制
c
14
math库
pow(x,1.0/n)
开x的n次方,开二次方为sqrt()
#include<cmath>cin>>n;double m=pow(n,1.0/3); //开三次方
ceil() 向上取整
取整用于模2余0.5情况
#include <iostream>
using namespace std;int main()
{int n;cin>>n;if(n%2==0)cout<<n/2<<endl;elsecout<<(n+1)/2<<endl;return 0;
}
真向上取整,适用于所有情况:
#include <iostream>
#include<cmath>
using namespace std;int main()
{int n;cin>>n;int m=ceil(n*1.0/2);cout<<m<<endl;return 0;
}
日期计算
#include<iostream>
using namespace std;
int main()
{int y,m,d;scanf("%d-%d-%d",&y,&m,&d);d-=2;if(d<=0){m--;if(m<1){y--;m+=12;}if(m>=1){if(m==1||m==3||m==5||m==7||m==8||m==10||m==12) d+=31;else if(m==2){if(y%400==0||(y%4==0&&y%100!=0)) d+=29;else d+=28;}else d+=30;}}printf("%d-%02d-%02d",y,m,d);return 0;
}
自测输入:2020-05-01
实际输出:2020-04-29
排除变量确定阈值
T-排队领水_ (nowcoder.com)
有不少于a个人在他前面,有不多于b个人在他后面,计算一下懒羊羊有多少个可能的位置
#include<iostream>
using namespace std;
int main()
{int n,a,b;cin>>n>>a>>b;if(n-b>a)cout<<b+1<<endl;else if(n-a<=b)cout<<n-a<<endl;return 0;
}
可知前面要大于等于a人,后面小于等于b人,当n-a<=b时,那么对于b这个变量怎么样都成立,写出有关于a的结果表达式即可。同理,当n-b>a时,可以不考虑a。
fib数列
a[1]=1,a[2]=1;for(int i=3;i<=n;i++){a[i]=a[i-1]+a[i-2];}cout<<a[n];
求绝对值abs()
#include <iostream>
#include<cmath>using namespace std;
int main()
{int a=1,b=10;float c=1.2,d=10.9;double e=1.123,f=10.2;cout<<"b-a="<<abs(b-a)<<endl;cout<<"c-d="<<abs(c-d)<<endl;cout<<"e-f="<<abs(e-f)<<endl;}
b-a=9
c-d=9.7
e-f=9.077
log函数
#include<stdio.h>
#include<math.h>
int main(){ printf("%f\n",log(10)); //以e为底的对数函数 printf("%f\n",log10(100)); //以10为底的对数函数 printf("%f\n",log(8)/log(2)); //计算log2^8,运用换底公式 printf("%f\n",exp(1)); //计算自然常数ereturn 0;
}
取精确小数
//法一:
if(ans>=11625907.5798&&ans<=11625907.5799)printf("%.7f \n",ans);//法二
if(abs(ans-11625907.5798)<0.0001)printf("%.7f \n",ans);
常见经典题
进制转换
二进制,八进制,十进制,十六进制的相互转换【简单易懂】
n进制转10进制
for(int i=0;i<s.size();i++){if(s[i]>'9')num=num*n+s[i]-'A'+10;else num=num*n+s[i]-'0';}
10进制转n进制
void hw(int sum,int n)
{int num=0;int c[10010]={0};string s="";while(sum){c[num++]=sum%n; //连除法sum/=n;}for(int i=num-1;i>=0;i--) //对应前面,“从下到上输出”{if(c[i]>=10) s+=(char)(c[i]+'A'-10); else s+=(char)(c[i]+'0');}cout<<s<<endl;}
1019-[NOIP2006]数列
对于n进制问题,我们可以尝试把n进制看出二进制的转换,然后通过%2求出’1‘的个数,以便于得到排序
//k进制 ,第n项
while(n!=0){if(n%2==1){sum+=pow(k,wei);}wei++;n/=2;}
判断质数
int zs(int n)
{if(n<2) return 0;for(int j=2;j<=sqrt(n);j++)if(n%j==0) return 0;return 1;
}
负数的进制转换
核心操作与正数一样,需要多解决在C++中取模给出了负数的问题
已知:商*除数+余数=被除数,则样例为 2 * (-7) + (-1) = -15,如何把余数变成正数?
简单的数学思想,加除数减除数即可: 2 * (-7) +(-7)-(-7)+ (-1) = -15 == 3*(-7)+6=-15
1028-[NOIP2000]进制转换
#include<bits/stdc++.h>
using namespace std ;
int main()
{int n , r ;long long ans=0 ;cin >> n >> r ;int m = n ;string s ;while(m){int mod = m%r ;if(mod < 0){mod -= r ; //余数-除数转为正m += r ; //加回去保证公式不变}char c = '0' + mod ;if(c > '9') c = 'A'+ (c -'0'-10) ;//转为数字再转字符s += c ;m /= r ;}if(n==0) s = "0" ;reverse(s.begin() , s.end()) ;cout << n << '=' << s << "(base" << r << ')' <<endl ;return 0 ;
}
反转字符串
#include<algorithm>reverse(s.begin(),s.end());
判断回文数
int huiw(int a)
{int ans=a,sum=0;while(a){sum=sum*10+a%10;a/=10;}if(sum==ans) return 1;return 0;
}
bool is_p(string n)
{for (int i = 0; i < n.size()/2+1; i ++)if (n[i] != n[n.size() - i - 1])return false;return true;
}
分解质因数
void divide(int x)
{for (int i = 2; i <= x / i; i ++ )if (x % i == 0)//i为质数{int s = 0;while (x % i == 0) x /= i, s ++ ;cout << i << ' ' << s << endl;}if (x > 1) cout << x << ' ' << 1 << endl;//最多只有一个大于平方根下n的质因子(两个相乘就大于n了)cout << endl;
}
蛇形与回型矩阵
回型:
#include <iostream>
using namespace std;//先初始化数组和想要输入的行数和列数
int q[105][105],n,m;
int main(){cin>>n;//定义我们的方向dx,dy,以及方向标”d“int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};int x=0,y=0,d=1;for(int i=1;i<=n*n;i++){q[x][y] = i;//每次a,b指下一个填数坐标int a =x+dx[d],b =y+dy[d];//考虑如果超出数组边界或者前方即将填的空格已经被填充了,则立即转变方向,改写a,bif(a<0 || a>=n || b<0 || b>=n || q[a][b]){d = (d+1)%4;a = x+dx[d],b = y+dy[d];}x = a,y =b;}for(int i=0;i<n;i++){for(int j=0;j<n;j++)cout<<q[i][j]<<" ";cout<<endl;}return 0;
}
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
蛇形
#include<iostream>
using namespace std;
int a[1000][1000];
int main()
{int n,i,j,sum=0;cin>>n;for(i=1;i<=2*n-1;i++)for(j=i;j>0;j--){//if(j<=n&&i+1-j<=n)sum++;if(i%2==0)a[i+1-j][j]=sum;elsea[j][i+1-j]=sum;}for(i=1;i<=2*n-1;i++){for(j=1;j<=2*n-1;j++)printf("%6d",a[i][j]);cout<<"\n";}
}
1 2 6 7 15 16 28
3 5 8 14 17 27 0
4 9 13 18 26 0 0
10 12 19 25 0 0 0
11 20 24 0 0 0 0
21 23 0 0 0 0 0
22 0 0 0 0 0 0
#include<iostream>
using namespace std;
int a[1000][1000];
int main()
{int n,i,j,sum=0;cin>>n;for(i=1;i<=2*n-1;i++)for(j=i;j>0;j--){if(j<=n&&i+1-j<=n)sum++;if(i%2==0)a[i+1-j][j]=sum;elsea[j][i+1-j]=sum;}for(i=1;i<=n;i++){for(j=1;j<=n;j++)cout<<a[i][j]<<" ";cout<<"\n";}
}
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
最大公约数与最小公倍数
求最大公约数gcd()
int gcd(int a,int b)
{int t;while(a%b){t=a%b;a=b;b=t;}return b;
}
最小公倍数:(a*b)/gcd(a,b)
实用技巧
string类型用printf输出
加 .c_ str()
#include<iostream>
using namespace std ;int main(){string str="hello";printf("%s",str.c_str()); // 调用c_str()函数return 0;
}
数组去重unique
假设有a = {1, 2, 2, 3, 3, 4, 4, 5, 5, 5} (使用unique必须先排序)
使用 unique()
函数去除重复元素,得到的结果是:a = {1, 2, 3, 4, 5, ?, ?, ?, ?, ?}
unique(a, a + n)
返回去重后数组的尾后迭代器,即指向数组中第一个未定义的元素的位置,a
是一个指向数组首元素的指针,所以 a
表示数组的起始地址,unique(a, a + n)-a
则可以得到去重后数组的长度
#include<iostream>
#include<algorithm>
using namespace std;int main() {int n;cin>>n;int a[n] ;for(int i = 0;i < n;i++){cin>>a[i];}//必须先排序 sort(a,a+n); for(int i = 0;i < n;i++){cout<<a[i]<<" ";}cout<<endl;//去重同时更新数组长度n=unique(a,a+n) -a; for(int i = 0;i < n;i++){cout<<a[i]<<" ";}cout<<endl;//去重后的数组长度cout<<n<<endl;}
input:
11
4 1 4 4 3 2 2 5 6 7 5
output:
1 2 2 3 4 4 4 5 5 6 7 //排序
1 2 3 4 5 6 7 //去重
7 //去重后数组元素个数
map的使用
#include<map>//常用
map<int,int> mp;
map<string,int> mp;mp[a[i]]++;for(auto it:mp)
{if(it.first==xx)cout<<it.second<<endl;
}//记录字符串
map<int, string> m;
// 用数组方式插入
m[123] = "dd";
m[456] = "ff";int len=mp.size();获取到map中映射的次数
typedef pair<int, int> PII;
map<PII,int> mp;mp[{x,y}] ++;
用十进制表达二进制(n>>i)%2
long long f(int n)
{long long sum=0;for(int i=30;i>=0;i--){sum=sum*10+(n>>i)%2;}return sum;
}
筛质数
void get_primes(int n)
{cnt=0;for(int i=2;i<=n;i++){if(!st[i]){primes[cnt++]=i;for(int j=i+i;j<=n;j+=i)st[j]=true;}}cout << cnt << endl;
}
//st[i]存储合数,primes[]存储质数
memset设置数组值
int A[2];
memset(A, -1, sizeof A); //只能赋0和-1
memset(A, 0, sizeof A); int a[100];
memset(a , 0x3f , sizeof a); //无穷大赋值
按字节赋值,要想赋值正确,value的值只能是-1或0,因为-1和0转化成二进制后每一位都是一样的,设int型占4个字节,则-1=0XFFFFFFFF, 0=0X00000000。
a的每个元素赋值为0x3f3f3f3f,十进制是 1061109567也就是10^9级别的
对结构体排序
1031-[NOIP2009]分数线划定
对于给出数字
id: f: 9848 90 6731 88 1422 95 8805 95 4162 88要求分数f降序排序,分数相同的则按id升序排序,得到如下:
1422 95 8805 95 9848 90 4162 88 6731 88
struct code{int a,b;
}s[5010];int cmp(code x,code y)
{if(x.b==y.b) return x.a<y.a;//分数相同则按id升序排return x.b>y.b;
}for(int i=0;i<n;i++)cin>>s[i].a>>s[i].b;//用结构体存储数字sort(s,s+n,cmp);
栈stack
#include<stack>
stack<int> q; //以int型为例
int x;
q.push(x); //将x压入栈顶
q.top(); //返回栈顶的元素
q.pop(); //删除栈顶的元素
q.size(); //返回栈中元素的个数
q.empty(); //检查栈是否为空,若为空返回true,否则返回false
set容器
内部元素有序
begin() ,返回set容器的第一个元素
end() ,返回set容器的最后一个元素
clear() ,删除set容器中的所有的元素
empty() ,判断set容器是否为空
size() ,返回当前set容器中的元素个数
s.erase() ,删除一个元素
int main(){set<int> s;s.insert(1);s.insert(2);s.insert(3);s.insert(1);cout<<"set 的 size 值为 :"<<s.size()<<endl;cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;cout<<"set 中 1 出现的次数是 :"<<s.count(1)<<endl;s.clear();if(s.empty()){cout<<"set 为空 !!!"<<endl;}return 0;
}
set 的 size 值为 :3
set 中的第一个元素是 :1
set 中的最后一个元素是:3
set 中 1 出现的次数是 :1
set 为空 !!!
大小根堆priority_queue
#include <queue>
priority_queue<int> q //大根堆
priority_queue<int,vector<int>,greater<int> > q //小根堆
#include <iostream>
#include<queue>
using namespace std;struct node{int x,y;bool operator< (const node &b) const{return this->y >b.y;}
};
// struct node{
// int x,y;
// bool operator< (const node &b) const{
// return this->x >b.x;
// }
// };int main()
{priority_queue<node> que;que.push((node){1,5});que.push((node){2,3});que.push((node){7,-1});que.push((node){-3,3});while(!que.empty()){cout<<que.top().x<<" "<<que.top().y<<endl;que.pop();}return 0;
}
大根堆对y从小到大排:
7 -1
2 3
-3 3
1 5
vector的erase
erase() 函数在删除元素时,会将删除位置后续的元素陆续前移,并将容器的大小减 1
#include <vector>
#include <iostream>
using namespace std;int main()
{vector<int>demo{ 1,2,3,4,5 };cout << "size is :" << demo.size() << endl;for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}cout<<endl;demo.erase(demo.begin() + 1);//删除元素 2//输出 dmeo 容器新的sizecout << "size is :" << demo.size() << endl;for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}return 0;
}
字符串操作
字符串查找find()
目标字符在字符串中第一次出现位置
str1.find(str2);//从串str1中查找时str2,返回str2中首个字符在str1中的地址str1.find(str2,5);//从str1的第5个字符开始查找str2string c="bob";
string s="abobwsdwdbobobobob";
int t=s.find(c);
//t输出1
找不到返回-1
if((int)s.find("str")!=-1) cnt++;//如果找到了则cnt++
//注意用(int)将-1变为数字
查找个数
string s="dede",f="666";ans=0,a=0;while(str.find(s,a)!=-1){a=str.find(s,a)+f.size()-1;ans++;}
数字转化为字符串to_string()
string s="";for(int i=1;i<=20;i++){s+=to_string(i);}cout<<s<<endl;
1234567891011121314151617181920
字符串转数字stoi()
#include<cstring>
string s = "12345";
int num1 = stoi(s);
字符串替换replace()
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{string s="abcdefghijklmn"; string t="1234"; s.replace(2,t.size(),t);//从第2个开始换,t.size为替换长度, t是要替换成的字符串cout<<s<<endl;return 0;
}
ab1234ghijklmn
sort对字符串长短排序
#include<algorithm>int cmp(string a,string b){return a.size()<b.size();
}string s[5];
sort(s+1,s+5,cmp);
字符串插入insert()
#include<iostream>
using namespace std;
int main()
{string str="abcdefg";string s="666";str.insert(1,s);//在原串下标为1的字符a前插入字符串scout<<str<<endl;string str1="hhhhhhhh";char c='w';str1.insert(4,5,c);//在原串下标为4的字符前插入5个字符ccout<<str1<<endl;string str2="oooooooo";string s2="abcdefg";str2.insert(0,s2,1,3);//将字符串s2从下标为1的b开始数3个字符,分别是bcd,插入原串的下标为0的字符前cout<<str2<<endl;return 0;
}
a666bcdefg
hhhhwwwwwhhhh
bcdoooooooo
ascll码表
字符串模拟练习
7-24 估值一亿的AI核心代码 - 团体天梯赛L1
L1-24估值一亿的AI核心代码 (20分)
#include <iostream>
#include<cstring>
#include<algorithm>
using namespace std;string old[100],ne[100];
int o,x;
int main()
{int n;cin >> n;getchar();string s;while (n--) {getline(cin, s);old[o++]=s;//找到其中第一个空格的位置string res = "";int i = 0;while (s[i] == ' ') i++;for (; i < s.size(); i++) {if (s[i] == ' ' && i + 1 < s.size() && isalnum(s[i + 1])) {res += s[i];//只有下面是字母的时候才会选择保留空格}if (s[i] != ' ') res += s[i];}//将?转化为!for (int i = 0; i < res.size(); i++) {if (res[i] == '?') res[i] = '!';if (res[i] >= 'A' && res[i] <= 'Z' && res[i] != 'I') {res[i] = 'a' + (res[i] - 'A');}}ne[x++]=res;}// for(int i=0;i<x;i++)// {// cout<<old[i]<<endl;// cout<<ne[i]<<endl;// }for(int i=0;i<x;i++){cout<<old[i]<<endl;for (int beg = 0;; beg++){beg = ne[i].find("can you", beg);if (beg == -1)break;//如果独立if ((beg == 0 || !isalnum(ne[i][beg-1])) && ( beg + 7 == ne[i].size() || !isalnum(ne[i][beg+7])) ){ne[i].replace(beg, 7, "A can");}}for (int beg = 0;; beg++){beg = ne[i].find("could you", beg);if (beg == -1)break;//如果独立if ((beg == 0 || !isalnum(ne[i][beg-1])) && ( beg + 9 == ne[i].size() || !isalnum(ne[i][beg+9]))){ne[i].replace(beg, 9, "A could");}}for (int beg = 0;; beg++){beg = ne[i].find("I", beg);if (beg == -1)break;//如果独立if ((beg == 0 || !isalnum(ne[i][beg-1])) && ( beg + 1 == ne[i].size() || !isalnum(ne[i][beg+1]))){ne[i].replace(beg, 1, "you");}}for (int beg = 0;; beg++){beg = ne[i].find("me", beg);if (beg == -1)break;//如果独立if ((beg == 0 || !isalnum(ne[i][beg-1])) && ( beg +2 == ne[i].size() || !isalnum(ne[i][beg+2]))){ne[i].replace(beg, 2, "you");}}for (int j = 0; j<ne[i].size(); j++){if (ne[i][j] == 'A') ne[i][j] = 'I';}cout << "AI: " << ne[i] << endl;} }
算法
二分查找模板
初始化时left=1,right=N+10;(left不用初始化为0)
版本1
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。
C++ 代码模板:
int bsearch_1(int l, int r)
{while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}return l;
}
版本2
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。
C++ 代码模板:
int bsearch_2(int l, int r)
{while (l < r){int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;}return l;
}
前缀和
一维前缀和
for(int i=1;i<=n;i++){cin>>a[i];s[i]=s[i-1]+a[i];//构造前缀和数组}while(q--){int l,r;cin>>l>>r;cout<<s[r]-s[l-1]<<endl;}
二维前缀和
for (int i = 1; i <= n; i ++ )for (int j = 1; j <= m; j ++ ){scanf("%d", &a[i][j]);//构造前缀和数组s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];}while (q -- ){int x1, y1, x2, y2;scanf("%d%d%d%d", &x1, &y1, &x2, &y2);//利用容斥原理printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);}
bfs模板
算法训练营 - 广度优先BFS_图的bfs模板
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;const int N = 110;
typedef pair<int, int> PII;
int n, m;
int g[N][N], d[N][N];int bfs()
{queue< pair<int, int> > q;q.push({0, 0});memset(d, -1, sizeof(d));d[0][0] = 0;int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};while (q.size())//队列不为空{PII t = q.front();//取队头元素q.pop();//出队for (int i = 0; i < 4; i++){int x = t.first + dx[i], y = t.second + dy[i];if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1){d[x][y] = d[t.first][t.second] + 1;//当前点到起点的距离q.push({x, y});//将新坐标入队}}}return d[n - 1][m -1];
}int main()
{cin >> n >> m;for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> g[i][j];cout << bfs() << endl;return 0;
}
高精度乘法
#include<bits/stdc++.h>
using namespace std;
int main(){int t;cin>>t;string a,b;while(t--){int ans[101]={0};//每一轮都要重置cin>>a>>b;int x=a.size(),y=b.size();for(int i=0;i<x;i++){for(int j=0;j<y;j++){ans[i+j]+=(a[i]-'0')*(b[j]-'0');//存储竖式上每一位的和}}for(int i=x+y-1;i>0;i--){ans[i-1]+=ans[i]/10;//进位ans[i]%=10;}for(int i=0;i<x+y-1;i++){printf("%d",ans[i]);}printf("\n");}return 0;
}
原理非常简单,模拟乘法运算,a0存最高位,乘法结果得数长度为a.size+b.size-1:
高精度加法
正序,相加,除前导0, 倒序输出
#include<bits/stdc++.h>
using namespace std;
int main()
{int t;cin>>t;while(t--){string s1,s2;cin>>s1>>s2;int a[5005]={0},b[5005]={0},c[5005]={0};int x=s1.size(),y=s2.size();for(int i=0;i<x;i++)a[i]=s1[x-i-1]-'0';for(int i=0;i<y;i++)b[i]=s2[y-i-1]-'0';int z=max(x,y);for(int i=0;i<z;i++){c[i]+=a[i]+b[i];c[i+1]=c[i]/10;c[i]=c[i]%10;}while(c[z]==0)//去除前导0z--;for(int i=z;i>=0;i--)cout<<c[i];cout<<endl;}
}
二叉树的构建与使用
//构建树vector<long long> tree[10010];for (int i = 2; i <= n; ++i) {ll parent;cin >> parent;tree[parent].push_back(i);}//n表示树的大小 //构建n-1个节点的位置,i表示节点,parent表示节点的父亲//遍历使用
void dfs(ll x)
{for (auto child : tree[x]) {dfs(child);}
}//可以遍历x为根的子树
dfs(x)