dfs_1:
//迷宫问题
#include<iostream>
#include<string>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//移动坐标
//建议按照 逆时针 (或顺时针)方向写,方便做转头操作
bool in(int x,int y){
return 0<=x && x<n && 0<=y && y<m;
}
bool dfs(int x,int y){
//找到重点
if(maze[x][y]=='T'){
return true;
}
vis[x][y]=1;//走过了
maze[x][y]='+';//标记为+
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
}
//走不通,取消标记
vis[x][y]=0;
maze[x][y]='.';
return false;
}
int main(){
//输入迷宫地图
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>maze[i];
}
//寻找起始点
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i,y=j;
}
}
}
//打印地图
if(dfs(x,y)){
for(int i=0;i<n;i++){
cout<<maze[i]<<endl;
}
} else {
cout<<"No!"<<endl;
}
return 0;
}
//
------------------------
//中国象棋
#include<iostream>
using namespace std;
char maze[15][15];//地图
int dir[8][2]={{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1}};//方向
bool vis[15][15];//标记是否走过
bool in(int x,int y){
return 0<=x&&x<10&&0<=y&&y<9;
}
bool dfs(int x,int y){
if(maze[x][y]=='T'){
return true;
}
vis[x][y]=true;
for(int i=0;i<8;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(maze[tx][ty]!='#' && in(tx,ty) && !vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
}
// vis[x][y]=false;这里我们如果不取消标记反而可以提高代码的运行效率。
//因为我们这里只需要判断两个点是否可达,到达过的状态就没有必要再次到达了。
return false;
}
int main(){
for(int i=0;i<10;i++){
cin>>maze[i];
}
int x,y;
for(int i=0;i<10;i++){
for(int j=0;j<9;j++){
if(maze[i][j]=='S'){
x=i;
y=j;
}
}
}
// dfs(x,y)
if(dfs(x,y)){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
return 0;
}
----------------------------------------
//迷宫最短路径
#include <iostream>
using namespace std;
int n,m,x,y;
int ans=1000000;
char maze[100][100];
bool vis[100][100];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool in(int x,int y){
return x>=0&&x<n&&y>=0&&y<m;
}
void dfs(int x,int y,int step){
if(maze[x][y]=='T'){
if(step<ans){
ans=step;
}
return;
}
vis[x][y]=1;
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
dfs(tx,ty,step+1);
}
}
vis[x][y]=0;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i;
y=j;
}
}
}
dfs(x,y,0);
cout<<ans<<endl;
} // namespace std;
-------------------------
//踏青
用 # 表示草地,用 . 表示空地
若相连的#表示为同一块草地,问共有几块
输入:
地图
输出:
草地块数
例子:
5 6
.#....
..#...
..#...
...##.
..#...
结果:4
*/
#include<iostream>
using namespace std;
char mp[105][105];
bool vis[105][105];
int n,m;
void dfs(int x,int y){
//不符合条件
if(x<0 || x>=n || y<0 || y>=m || vis[x][y] || mp[x][y]=='.' ){
return ;
}
vis[x][y]=true;
dfs(x-1,y);
dfs(x+1,y);
dfs(x,y-1);
dfs(x,y+1);
}
int main(){
cin>>n>>m;
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>mp[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(!vis[i][j] && mp[i][j]=='#'){
cnt++;
dfs(i,j);
cout<<i<<j<<endl;
}
}
}
cout<<cnt<<endl;
return 0;
}
-----------------
//迷宫方案数
#include <iostream>
using namespace std;
int n,m,x,y,ans;
char maze[100][100];
bool vis[100][100];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool in(int x,int y){
return x>=0&&x<n&&y>=0&&y<m;
}
void dfs(int x,int y){
if(maze[x][y]=='e'){
ans++;
return;
}
vis[x][y]=1;
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='#'&&!vis[tx][ty]){
dfs(tx,ty);
}
}
vis[x][y]=0;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='s'){
x=i,y=j;
}
}
}
dfs(x,y);
cout<<ans<<endl;
return 0;
}
----------------------------------
//最大蛋糕
#include <iostream>
using namespace std;
int n,m,cnt,ans;
char maze[100][100];
bool vis[100][100];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool in (int x,int y){
return x<n&&x>=0&&y<m&&y>=0;
}
void dfs(int x,int y){
if(x<0||x>=n||y<0||y>=n||vis[x][y]||maze[x][y]=='.'){
return;
}
vis[x][y]=1;
cnt++;
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]=='#'&&!vis[tx][ty]){
dfs(tx,ty);
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!vis[i][j]&&maze[i][j]=='#'){//没有访问过!!并且是#
cnt=0;
dfs(i,j);
if(cnt>ans){
ans=cnt;
}
}
}
}
cout<<ans<<endl;
} // namespace std;
-------------------
//家谱
#include<iostream>
#include<vector>
using namespace std;
vector<int> son[100005];//记录
bool f[100005];//为了确定根
int ans[100005];//答案数组
int dfs(int u) {//计算这一代的人数
int ret=0;
//先统计包括自己的后代
for(int i=0; i<son[u].size(); i++) {
ret+=dfs(son[u][i]);
}
ans[u]=ret;
return ret+1;//int型返回值代表这一代的人数
}
int main() {
int x,y,n,u;
cin>>n;
for(int i=0; i<n-1; i++) {
cin>>x>>y;
son[x].push_back(y);
f[y]=true;
}
for(int i=1; i<=n; i++) {
if(!f[i]) {
u=i;//u代表根节点
break;
}
}
dfs(u);//传入根节点
for(int i=1; i<=n; i++) {
cout<<ans[i]<<endl;
}
return 0;
}
--------------------
//马的覆盖点
#include<iostream>
using namespace std;
/*马可以走到哪里
输入棋盘的大小 nXm 输入马的起始位置 (x,y)
输出马三步以内可以到达的位置,用 # 表示
*/
int n,m;
char mp[105][105];
bool vis[105][105];
int a[8][2]= {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};
void dfs(int x,int y,int step) {
if(x<0 || x>=n || y<0 || y>=m ) {
return ;
}
if(step >3) {
return ;
}
mp[x][y]='#';
for(int i=0; i<8; i++) {
dfs(x+a[i][0],y+a[i][1],step+1);
//step++ (X) ++step(X) ?
}
}
int main() {
cin>>n>>m;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
mp[i][j]='.';
}
}
int x,y;
cin>>x>>y;
mp[x][y]='B';
dfs(x-1,y-1,0);
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cout<<mp[i][j];
}
cout<<endl;
}
return 0;
}
------------------
#include<bits/stdc++.h>
#define ll long long
#define N 100010
using namespace std;
const ll maxn = 1e2 + 5;
//ll a[maxn],b[maxn];
//bool vis[maxn];
int ans[maxn];
vector<int>v[maxn];
int n, m;
bool vis[maxn][maxn][2];
bool flag;
char a[maxn][maxn];
void dfs(int x,int y,int d)
{
if(x>=n||x<0||y>=m||y<0||vis[x][y][d]||a[x][y]=='#')
return ;
vis[x][y][d]=true;
dfs(x+(2-d),y,d);
dfs(x-(2-d),y,d);
dfs(x,y+(2-d),d);
dfs(x,y-(2-d),d);
return;
}
int main() {
int x, y, tx, ty;
cin >> n >> m;
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(a[i][j] == 'w') {
x = i;
y = j;
} else if(a[i][j] == 'g') {
tx = i;
ty = j;
}
bool flag=false;
dfs(x, y, 0);
dfs(tx, ty, 1);
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(vis[i][j][0]&&vis[i][j][1])
flag=true;
if(flag)
cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
------------------
//蒜头军开公司
#include<iostream>
using namespace std;
int task[15][15];
int vis[15];
int n;
int ans = 9999999;
void dfs(int step, int t)
{
if (step == n)
{
ans = min(ans, t);
return;
}
for (int i = 0; i < n; i++)
{
if (!vis[i])
{
vis[i] = 1;
dfs(step + 1, t + task[step][i]);
vis[i] = 0;
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> task[i][j];
}
}
dfs(0, 0);
cout << ans <<endl;
return 0;
}
----------------
dfs_2:
#include<iostream>
using namespace std;
int n,k,sum,ans;
int a[100];
void dfs(int i,int cnt,int s){
if(i==n){
if(cnt==k && s==sum){
ans++;
}
return ;
}
dfs(i+1,cnt,s);//不选 a[i]
dfs(i+1,cnt+1,s+a[i]);//选 a[i]
}
int main(){
cin>>n>>k>>sum;
for(int i=0;i<n;i++){
cin>>a[i];
}
ans=0;
dfs(0,0,0);
cout<<ans<<endl;
return 0;
}
/*
输入:
5 3 9
1 2 3 4 5
输出:
2
*/
---------------
#include<iostream>
using namespace std;
int n,k,sum,ans,a[110];
bool xuan[110];//标记每个数是否被选
void dfs(int s,int cnt) {
if(cnt==k && s==sum) {
ans++;
}
for(int i=0; i<n; i++) {
if(!xuan[i]) {
xuan[i]=true;
dfs(s+a[i],cnt+1);
xuan[i]=false;
}
}
}
int main() {
cin>>n>>k>>sum;
for(int i=0; i<n; i++) {
cin>>a[i];
}
ans=0;
dfs(0,0);
cout<<ans<<endl;
return 0;
}
/*
输入:5 3 9
1 2 3 4 5
输出:12 (错误)
原因:系统把 2 3 5 , 2 5 3 ,3 2 5...当成不同的选择
改正:除以 k 的阶乘
int k2=1;
for(int i=1;i<=k;i++){
k2*=i;
}
cout<<ans/k2<<endl;
*/
------------------------
/*现在给定n根木棍,现在问用这些木棍能不能拼成一个等边三角形(要求这些木棍全部用到)*/
#include<iostream>
using namespace std;
int n,sum=0;
int l[105];
bool dfs(int a,int b,int c,int i){//i代表选的根数
//cout<<"a "<<a<<" b "<<b<<" c "<<c<<" i "<<i<<endl;
if(a==b && a==c && i==n){
//cout<<"yes"<<endl;
return true;
}
if(a>sum/3 || b>sum/3 || c>sum/3){
return false;
}
bool a1=dfs(a+l[i],b,c,i+1);
bool a2=dfs(a,b+l[i],c,i+1);
bool a3=dfs(a,b,c+l[i],i+1);
if(a1||a2||a3){
return true;
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>l[i];
sum+=l[i];
}
if(sum%3!=0 ){
cout<<"no"<<endl;
return 0;
}
int a=0,b=0,c=0;//代表每一根的和
bool d=dfs(a,b,c,0);
if(d){
cout<<"yes"<<endl;
} else{
cout<<"no"<<endl;
}
return 0;
}
-------------
//八皇后
#include<iostream>
using namespace std;
int ans=0;
bool col[10],x1[20],x2[20];//列,对角线1,对角线2
bool check(int r,int i){
return !col[i] && !x1[r+i] && !x2[r-i+8];
}
void dfs(int r){
for(int i=0;i<8;i++){//行
if(r==8){
ans++;
return;
}
if(check(r,i)){
col[i]=x1[r+i]=x2[r-i+8]=true;
//r-i+8 防止负坐标
dfs(r+1);
col[i]=x1[r+i]=x2[r-i+8]=false;
}
}
}
int main(){
dfs(0);
cout<<ans<<endl;
return 0;
}
/*没有输入,输出 92
八皇后问题有92组解
*/
----------------------
//等边三角形
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int k[30],p[10],x[10];
int n,M,count,sum=0;
double w,mypow[160][5];
void dfs(int a){
if(a==0){//当1~n位置已经赋值
for(int i=1;i<=n;i++){//循环计算每一组k,x,p
w=mypow[x[i]][p[i]];
sum+=(int)w*k[i];
}
if(sum==0){
count++;
}
return ;//循环当前位置的下一个数
}
for(int i=1;i<=M;i++){
x[a]=i;//给当前位置赋值
sum=0;//计算前先将sum清零
dfs(a-1);
}
}
int main(){
scanf("%d",&n);
scanf("%d",&M);
for(int i=1;i<=n;i++){
scanf("%d",&k[i]);
scanf("%d",&p[i]);
}
for(double i=1;i<=150;i++){//此处用i<=M,内循环用i<=n会有测试数据不通过,?也许是因为测试数据在演我
for(double j=1;j<=4;j++){
mypow[(int)i][(int)j]=pow(i,j);//数组下标必须为整型,并且double=pow[double,double] //用二维数组存储pow结果,如果在递归中用pow计算,会需要大量时间
}
}
dfs(n);
printf("%d",count);
return 0;
}
----------------------
//方程的解
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int k[30],p[10],x[10];
int n,M,count,sum=0;
double w,mypow[160][5];
void dfs(int a){
if(a==0){//当1~n位置已经赋值
for(int i=1;i<=n;i++){//循环计算每一组k,x,p
w=mypow[x[i]][p[i]];
sum+=(int)w*k[i];
}
if(sum==0){
count++;
}
return ;//循环当前位置的下一个数
}
for(int i=1;i<=M;i++){
x[a]=i;//给当前位置赋值
sum=0;//计算前先将sum清零
dfs(a-1);
}
}
int main(){
scanf("%d",&n);
scanf("%d",&M);
for(int i=1;i<=n;i++){
scanf("%d",&k[i]);
scanf("%d",&p[i]);
}
for(double i=1;i<=150;i++){//此处用i<=M,内循环用i<=n会有测试数据不通过,?也许是因为测试数据在演我
for(double j=1;j<=4;j++){
mypow[(int)i][(int)j]=pow(i,j);//数组下标必须为整型,并且double=pow[double,double] //用二维数组存储pow结果,如果在递归中用pow计算,会需要大量时间
}
}
dfs(n);
printf("%d",count);
return 0;
}
---------------------
//数独
#include<iostream>
using namespace std;
char s[10][10];
bool f;
bool vx[10][10];//每一行能否填几
bool vy[10][10];
bool vv[10][10];//单个3X3的格子能否填几
void dfs(int x,int y) {
if(f) {
return;
}
if(x==9) {
f=true;
//找到一个后输出
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
cout<<s[i][j]<<" ";
}
cout<<endl;
}
return ;
}
if(y==9 ) {
dfs(x+1,0);
return;
}
if(s[x][y]!='*') {
dfs(x,y+1);
return ;
}
for(int i=1; i<=9; i++) {
if(!vx[x][i] && !vy[y][i] && !vv[x / 3 * 3 + y / 3][i]) {
s[x][y]='0'+i;
vx[x][i]=true;
vy[y][i]=true;
vv[x/3*3+y/3][i]=true;
dfs(x,y+1);
vx[x][i]=false;
vy[y][i]=false;
vv[x/3*3+y/3][i]=false;
s[x][y]='*';
}
}
}
int main() {
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
cin>>s[i][j];
}
}
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
if(s[i][j]!='*') {
vx[i][s[i][j]-'0']=true;
vy[j][s[i][j]-'0']=true;
vv[i/3*3+j/3][s[i][j]-'0']=true;
}
}
}
dfs(0,0);
return 0;
}
-------------------
//2n皇后
#include<iostream>
using namespace std;
int mp[10][10];
int vy[10],vd1[20],vd2[20];//行,列,对角线1,对角线2
int n;
int ans;
void dfs(int x,int p){
if(x==n && p==2 ){ //p: 一表示放黑的,二表示方白的,零表示都可以,先放黑后放白
ans++;
return;
}
if(x==n ){
dfs(0,p+1);
return;
}
for(int i=0;i<n;i++){
if(mp[x][i] && vy[i]!=3 && vy[i]!=p && vd1[x+i]!=3 &&
vd1[x+i]!=p && vd2[x-i+n]!=3 && vd2[x-i+n]!=p ){
mp[x][i]=0;
vy[i]+=p;
vd1[x+i]+=p;
vd2[x-i+n]+=p;
dfs(x+1,p);
vy[i]-=p;
vd1[x+i]-=p;
vd2[x-i+n]-=p;
mp[x][i]=1;
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>mp[i][j];
}
}
dfs(0,1);
cout<<ans<<endl;
return 0;
}
--------------------
//引爆炸弹
#include<iostream>
using namespace std;
char s[1005][1005];
bool vx[1005],vy[1005];
int n,m,cnt;
void dfs(int x,int y){
s[x][y]='0';
if(!vx[x]){
vx[x]=true;
for(int i=0;i<m;i++){
if(s[x][i]=='1'){
dfs (x,i);
}
}
}
if(!vy[y]){
vy[y]=true;
for(int i=0;i<n;i++){
if(s[i][y]=='1'){
dfs(i,y);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>s[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='1'){
cnt++;
dfs(i,j);
}
}
}
cout<<cnt<<endl;
return 0;
}
/*
样例输入:
5 5
00010
00010
01001
10001
01000
样例输出:
2
*/
bfs_1:
---------------
约瑟夫!!!
#include<iostream>
#include<queue>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
queue<int> q;
for(int i=1;i<=n;i++){
q.push(i);
}
int cur=1;
while(q.size()>1){
int x=q.front();
q.pop();
if(cur!=m){
q.push(x);
cur++;
} else{
cur=1;
}
}
cout<<q.front()<<endl;
}
-----------------------
//迷宫bfs
#include<iostream>
#include<queue>
using namespace std;
int n,m;
char maze[105][105];
bool vis[105][105];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//方向
bool in(int x,int y){//范围
return x>=0 && x<n && y>=0 && y<m;
}
//节点
struct node{
int x,y,d;
node(int xx,int yy,int dd){
x=xx;
y=yy;
d=dd;
}
};
int bfs(int sx,int sy){
queue<node> q;
q.push(node(sx,sy,0));
vis[sx][sy]=true;
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=now.x+dir[i][0];
int ty=now.y+dir[i][1];
if(in(tx,ty) && maze[tx][ty]!='*' && !vis[tx][ty]){
if(maze[tx][ty]=='T'){
return now.d +1;
}else{
vis[tx][ty]=true;
q.push(node(tx,ty,now.d+1));
}
}
}
}
return -1;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i;
y=j;
}
}
}
cout<<bfs(x,y)<<endl;
return 0;
}
/*
样例输入:
5 6
....S*
.**...
.*..*.
*..**.
.T....
样例输出:
7
-------------
//一维度坐标
/*在长度为【0,n】的一维坐标中,输入A,B的地址,问能否从A到B。
移动方式:向前一步(坐标+1),向后一步(坐标-1),跳(坐标*2)*/
#include<iostream>
#include<queue>
#include<utility>
using namespace std;
bool vis[100];
int main() {
int n,A,B,now,step;
cin>>n>>A>>B;
queue< pair<int,int> >q;
q.push(make_pair(A,0));
vis[A]=true;
while(!q.empty()) {
now=q.front().first;
step=q.front().second;
q.pop();
if(now==B){
cout<<step<<endl;
break;
}
if(now+1<=n && !vis[now+1]) {
q.push(make_pair(now+1,step+1));
vis[now+1]=true;
}
if(now-1>=0 && !vis[now-1]) {
q.push(make_pair(now-1,step+1));
vis[now-1]=true;
}
if(now*2<=n && !vis[now*2]) {
q.push(make_pair(now*2,step+1));
vis[now*2]=true;
}
}
return 0;
}
/*
样例输入:
10 2 7
样例输出
3
*/
-------------------
//密码锁
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
struct node {
int num[4],step;
} first,last;
int vis[11][11][11][11];
void bfs() {
int i;
node a,next;
queue<node> q;
a=first;
a.step=0;
q.push(a);
memset(vis,0,sizeof(vis));
vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]]=1;
while(!q.empty()) {
a=q.front();
q.pop();
//bfs出口
if(a.num[0]==last.num[0] && a.num[1]==last.num[1]
&&a.num[2]==last.num[2] &&a.num[3]==last.num[3] ) {
cout<<a.step<<endl;
return;
}
for(int i=0; i<4; i++) { //++1
next=a;
next.num[i]++;
if(next.num[i]==10) {
next.num[i]=1;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
for(int i=0; i<4; i++) { //--1
next=a;
next.num[i]--;
if(next.num[i]==0) {
next.num[i]=9;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
for(int i=0; i<3; i++) {//交换
next=a;
next.num[i]=a.num[i+1];
next.num[i+1]=a.num[i];
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]) {
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
}
}
int main() {
int i,j,k;
char s1[10],s2[10];
cin>>s1>>s2;
for(int i=0; i<4; i++) {
first.num[i]=s1[i]-'0';
last.num[i]=s2[i]-'0';
}
bfs();
return 0;
}
/*
样例输入:
1234
2144
样例输出:
2
*/
-----------------
//乳草的侵占
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct node{
int x, y;
node(){}
node(int _x, int _y)
{
x = _x;
y = _y;
}
};
int n, m, u, v;
char mp[110][110];
int vis[110][110];
int dx[] = {1, -1, 0, 0, -1, 1, -1, 1};//8个方向
int dy[] = {0, 0, 1, -1, 1, 1, -1, -1};
int bfs()
{
vis[u][v] = 1;//标记访问
queue<node> q;
q.push(node(u, v));
int ma = -1;
while (!q.empty())
{
u = q.front().x;
v = q.front().y;
q.pop();
for (int i = 0; i < 8; i++)
{
int x = u + dx[i];
int y = v + dy[i];
if (x >= 1 && x <= n && y >= 1 && y <= m && mp[x][y] == '.' && !vis[x][y])
{
q.push(node(x, y));
vis[x][y] = vis[u][v] + 1;
ma = vis[x][y];//记录时间
}
}
}
return ma - 1;
}
int main()
{
cin >> m >> n >> v >> u;
u = n - u + 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> mp[i][j];//输入
}
}
cout << bfs() << endl;
return 0;
}
-----------------
//一维跳棋
#include<bits/stdc++.h>
using namespace std;
int n;
string s1,s2;
vector<int> temp;
struct Node{
string s;
int ind;//空格位置
vector<int> vc;
};
void bfs(){
queue<Node> q;
q.push({s1,n,temp});
while(!q.empty()){
Node now=q.front();
temp=now.vc;
q.pop();
if(now.s==s2){//合法结束状态结束搜索
for(int i=0;i<temp.size();i++){
cout<<temp[i]+1;
if((i+1)%5!=0) cout<<" ";
else cout<<endl;
}
break;
}
if(now.ind-1>=0){//左边棋子和右边空格交换
if(now.s[now.ind-1]=='W'){
Node next=now;
swap(next.s[now.ind-1],next.s[now.ind]);
temp.push_back(now.ind-1);
q.push({next.s,now.ind-1,temp});
temp.pop_back();
}
}
if(now.ind-2>=0&&now.s[now.ind-1]=='B'&&now.s[now.ind-2]=='W'){//左边棋子跳到右边空格
Node next=now;
swap(next.s[now.ind-2],next.s[now.ind]);
temp.push_back(now.ind-2);
q.push({next.s,now.ind-2,temp});
temp.pop_back();
}
if(now.ind+1<2*n+1){//右边棋子和左边空格交换
if(now.s[now.ind+1]=='B'){
Node next=now;
swap(next.s[now.ind+1],next.s[now.ind]);
temp.push_back(now.ind+1);
q.push({next.s,now.ind+1,temp});
temp.pop_back();
}
}
if(now.ind+2<2*n&&now.s[now.ind+1]=='W'&&now.s[now.ind+2]=='B'){//右边棋子跳到左边空格
Node next=now;
swap(next.s[now.ind+2],next.s[now.ind]);
temp.push_back(now.ind+2);
q.push({next.s,now.ind+2,temp});
temp.pop_back();
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
s1+='W';
s2+='B';
}
s1+=' ';
s2+=' ';
for(int i=n+1;i<2*n+1;i++){
s1+='B';
s2+='W';
}
bfs();
return 0;
}
------------------
//三阶魔方
#include<iostream>
#include<map>
#include<queue>
#include<cstdio>
using namespace std;
struct node{
int a[3][3];
bool operator < (const node &x) const{
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]<x.a[i][j]){
return 1;
}
}
}
return 0;
}
bool operator == (const node &x) const{
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(a[i][j]!=x.a[i][j]){
return 0;
}
}
}
return 1;
}
void print(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int tonum(){
int res=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
res=res*10+a[i][j];
}
}
return res;
}
} init;
node rotate(node a,int s,int d){
node res=a;
if(d==-1){ //right move
int tmp=res.a[s][2];
res.a[s][2]=res.a[s][1];
res.a[s][1]=res.a[s][0];
res.a[s][0]=tmp;
}else if(d==1){ // left move
int tmp=res.a[s][0];
res.a[s][0]=res.a[s][1];
res.a[s][1]=res.a[s][2];
res.a[s][2]=tmp;
}else if(d==-2){ //up move
int tmp=res.a[0][s];
res.a[0][s]=res.a[1][s];
res.a[1][s]=res.a[2][s];
res.a[2][s]=tmp;
} else if(d==2){ // down move
int tmp=res.a[2][s];
res.a[2][s]=res.a[1][s];
res.a[1][s]=res.a[0][s];
res.a[0][s]=tmp;
}
return res;
}
int bfs(node st){
queue<node> q;
map<int,int> d;
q.push(st);
d[st.tonum()]=0;
while(!q.empty()){
node x=q.front();
q.pop();
int tt=x.tonum();
if(x==init){
return d[x.tonum()];
}
node tmp;
for(int i=0;i<3;i++){
tmp=rotate(x,i,-1);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
tmp=rotate(x,i,1);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
}
for(int i=0;i<3;i++){
tmp=rotate(x,i,-2);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
tmp=rotate(x,i,2);
if(!d.count(tmp.tonum())){
d[tmp.tonum()]=d[tt]+1;
q.push(tmp);
}
}
}
return -1;
}
int main(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
init.a[i][j]=i*3+j+1;
}
}
node t;
for(int i=0;i<3;i++){
int n;
cin>>n;
t.a[i][2]=n%10;
n/=10;
t.a[i][1]=n%10;
n/=10;
t.a[i][0]=n;
}
int ans=bfs(t);
cout<<ans<<endl;
return 0;
}
/*
样例输入:
412
756
389
样例输出:
2
*/
------------------
//吃糖时间
#include<iostream>
#include<queue>
#include<vector>
#include<cstdlib>
using namespace std;
typedef struct{
int v;
int step;
}node;
int maxn;
queue<node> q;
vector<int> g[100010];
bool vis[100010];
void bfs(){
int i;
node p,t;
while(!q.empty()){
p=q.front();
q.pop();
for(int i=0;i<g[p.v].size();i++){
t.v=g[p.v][i];
t.step=p.step+1;
if(!vis[t.v]){
q.push(t);
vis[t.v]=1;
if(t.step>maxn){
maxn=t.step;
}
}
}
}
}
int main(){
node t;
int n,p,c,m,a,b,i;
cin>>n>>p>>c;
cin>>m;
for(int i=0;i<p;i++){
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
t.v=c;
t.step=1;
vis[t.v]=1;
q.push(t);
bfs();
cout<<maxn+m<<endl;
return 0;
}
/*
样例输入:
4 3 1
2
1 2
2 3
1 4
样例输出:
5
*/
递推:
//错排
#include<iostream>
using namespace std;
const int N=1e3+9;
long long f[N];
int main(){
int n;
cin>>n;
//方法一:数组存储
f[1]=0,f[2]=1;
for(int i=3;i<=n;i++){
f[i]=(f[i-1]+f[i-2])*(i-1);
}
cout<<f[n]<<endl;
//方法二:空间优化
long long a=0,b=1,c=1;
for(int i=3;i<=n;i++){
c=(a+b)*(i-1);
a=b;
b=c;
}
if(n!=1){a
cout<<c<<endl;
}else{
cou<<0<<endl;
}
}
-------------------------
//杨辉三角
#include<iostream>
using namespace std;
int n;
int a[10][10]= {0};
int main() {
cin>>n;
a[0][0]=1;
for(int i=1; i<n; i++) {
a[i][0]=1;
for(int j=1; j<n; j++) {
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
cout<<a[i][j]<<" ";
}
cout<<endl;
}
int m;
cin>>m;
cout<<a[n-1][m-1]<<endl;
return 0;
}
/*
5
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1
3
6
*/
------------------
//过河卒
#include<iostream>
using namespace std;
int dir[8][2]= {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};
bool d[30][30];
long long dp[30][30];
int main() {
int n,m,cx,cy;// n,m棋盘大小 cx,xy马的位置
cin>>n>>m>>cx>>cy;
d[cx][cy]=true;
for(int i=0; i<8; i++) {
int tx=cx+dir[i][0];
int ty=cy+dir[i][1];
if(tx>=0 && tx<=n && ty>=0 && ty<=n) {
d[tx][ty]=true;//记录为马控制点
}
}
dp[0][0]=1;//dp[n][m]即为从(0,0)到(n,m)的路径数目
for(int i=0; i<=n; i++) {
for(int j=0; j<=m; j++) {
if(d[i][j]==false) {
if(i) {
dp[i][j]+=dp[i-1][j];
}
if(j) {
dp[i][j]+=dp[i][j-1];
}
}
}
}
cout<<dp[n][m]<<endl;
return 0;
}
/*
样例输入:
5 5 2 4
样例输出:
14
*/
-----------------
//迷宫最短路 dp 版
/*输入一张地图,求从左上角到右下角的最短路径长,只能往右/下方向移动*/
#include<iostream>
#include<algorithm>
using namespace std;
int a[110][110];
int dp[110][110];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
dp[1][1]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==1 && j==1){
continue;
}else if(i==1){
dp[i][j]=dp[i][j-1]+a[i][j];
}else if(j==1){
dp[i][j]=dp[i-1][j]+a[i][j];
}else{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+a[i][j];
}
}
}
cout<<dp[n][n]<<endl;
return 0;
}
/*
样例输入:
3
0 3 4
6 2 5
5 4 3
样例输出:
12
*/
---------
//数字三角形回家
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a[105][105]={0};
int dp[105][105]={0};
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
for(int j=1; j<=i; j++) {
cin>>a[i][j];
}
}
int ans=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=i; j++) {
dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i-1][j-1]);
if(i==n){
ans=max(dp[i][j],ans);
}
}
}
cout<<ans<<endl;
cout<<"--输出dp数组--"<<endl;
for(int i=1; i<=n; i++) {
for(int j=1; j<=i; j++) {
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
/*
样例输入:
4
3
1 2
6 2 3
3 5 4 1
样例输出:
15
--输出dp数组--
3
4 5
10 7 8
13 15 12 9
*/
-------------
//编辑距离
#include<iostream>
#include<cstring>
using namespace std;
int dp[105][105];
string a,b;
int main(){
cin>>a>>b;
int lena=a.size();
int lenb=b.size();
for(int i=1;i<=lena;i++){
dp[i][0]=i;
}
for(int i=1;i<=lenb;i++){
dp[0][1]=i;
}
for(int i=1;i<=lena;i++){
for(int j=1;j<=lenb;j++){
if(a[i-1]==b[i-1]){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
}
}
}
cout<<dp[lena][lenb]<<endl;
return 0;
}
/*
cin:
abcd
acef
cout:
3
*/
日期/字符串/进制转换:
-------------------------------------------
1.模拟法:记住某天是星期几(例如公元1月1日是星期一),然后一天天模拟计算
#include<iostream>
using namespace std;
int whatday(int y,int m,int d){
int ans=0;
//计算过去当前年之后是星期几,从1月1日星期一开始计算
for(int i=1;i<y;i++){
if((i%100!=0 && i%4==0) || (i%400==0) ){
//闰年
ans+=366%7;//
ans %=7;
} else{
ans += 365%7;
ans %= 7;
}
}
//计算过去当前月之后,是星期几
for(int i=1;i<m;i++){
if(i==1 || i==3 || i==5 || i==7 || i==8 || i==10 || i==12){
ans+=31%7;
ans%=7;
} else if(i==4 || i==6 || i==9 || i==11){
ans+=30%7;
ans%=7;
}else if((y%100!=0 && y%4==0)|| y%400==0){
ans+=29%7;
ans%=7;
}else{
ans+=28%7;
ans%=7;
}
}
//计算过去几天后
ans+=(d-1)%7;
ans %= 7;
return ans;
}
string weekday[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
int main() {
int y,m,d;
cin>>y>>m>>d;
cout<<weekday[whatday(y,m,d)]<<endl;
}
2.菜吉姆拉尔森计算公式:设星期为w,年份为y,月份为m,日期为d
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7
在把计算的w+1就是真正的星期几
注:每年的1,2月要当成上一年的13,14月来计算
int main() {
//w=(d+2xm+3x(m+1)/5+y+y/4-y/100+y/400)%7
int w,d,m,y;
cout<<"年"; cin>>y;
cout<<"月"; cin>>m;
cout<<"日"; cin>>d;
if(m==1){
m=13;
y=y-1;
}
if(m==2){
m=14;
y=y-1;
}
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
cout<<"星期"<<w+1<<endl;
return 0;
}
-----------------------
输入:一个开始日期 几天后
输出:一个日期
#include <bits/stdc++.h>
using namespace std;
int main(){
int year,month,day,n;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
while(scanf("%d-%d-%d%d",&year,&month,&day,&n)!=EOF){
if((year%4==0&&year%100!=0)||year%400==0){//判断闰年
mon[2]=29;
}
else
mon[2]=28;
for(int i=1;i<=n;i++){
day+=1;
if(day>mon[month]){
day=day-mon[month];
month++;
if(month>12){
year++;
month=1;
if((year%4==0&&year%100!=0)||year%400==0){//判断闰年
mon[2]=29;
}
else
mon[2]=28;
}
}
}
printf("%02d-%02d-%02d\n",year,month,day);
}
return 0;
}
---------------------------
进制转换:
#include<bits/stdc++.h>
using namespace std;
string s;
//16-10-8
int f(string s){
int sum=0;
for(int i=0;i<s.length();i++){
if(s[i]>='A'&&s[i]<='F')
sum=sum*16+s[i]-'A'+10;
else
sum=sum*16+s[i]-'0';
}
int t[100],num=0;
while(sum>0){
t[num++]=sum%8;
sum/=8;
}
for(int i=sum-1;i>=0;i--){
cout<<t[i];
}
}
int main(){
cin>>s;
f(s);
return 0;
}
--------------------------
#include<bits/stdc++.h>
using namespace std;
int main(){
string str ="123456789abcdefghiaklmn";
for(int i=0;i<10;i++) //把str看成一个字符串数组
cout<<str[i]<<" ";
cout << endl;
//find函数
cout<<"123的位置: "<<str.find("123")<<endl;
//输出:123的位置: 0
cout<<"34在str[2]到str[n-1]中的位置: "<<str.find("34",2)<<endl;
//输出:34在str[2]到str[n-1]中的位置: 2
cout<<"ab在str[0]到str[12]中的位置: "<<str.rfind("ab",12)<<endl;
//输出:ab在str[0]到str[12]中的位置: 9
//substr()函数
cout<<"str[3]及以后的子串:"<<str.substr(3)<<endl;
//输出:str[3]及以后的子串:456789abcdefghijklmn
//若小于限制长度则报错
cout<<"从str[2]开始的4个字符:"<<str.substr(2,4)<<endl;
//输出:从str[2]开始的4个字符:3456
//find()函数
str.replace(str.find("a"), 5, "@#");
cout<<str<<endl;
//输出:123456789@#fghiaklmn
//insert()函数
str.insert(2, "***");
cout<<"从2号位置插入: "<<str<<endl;
//输出:12***3456789@#fghiaklmn
//添加字符串:append()函数
str.append("$$$");
cout<<"在字符串str后面添加字符串:"<<str<<endl;
//输出: 12***3456789@#fghiaklmn$$$
//字符串长度
cout<<str.size()<<endl;
cout<<str.length()<<endl;
//交换字符串:swap()函数
string str1="aaa",str2="bbb";
swap(str1, str2);
cout<<str1<<" "<<str2<<endl;
//字符串比较函数:compare(),相等输出0,不等输出1
cout<<str1.compare(str2)<<endl;
if(str1==str2) cout <<"=="; //直接比较也行
if(str1!=str2) cout <<"!=";
return 0;
}
c++(stl):
vector, 变长数组,倍增的思想
size() 返回元素个数
empty() 返回是否为空
clear() 清空
front()/back()
push_back()/pop_back()
begin()/end()
[]
支持比较运算,按字典序
pair<int, int>
first, 第一个元素
second, 第二个元素
支持比较运算,以first为第一关键字,以second为第二关键字(字典序)
string,字符串
size()/length() 返回字符串长度
empty()
clear()
substr(起始下标,(子串长度)) 返回子串
c_str() 返回字符串所在字符数组的起始地址
queue, 队列
size()
empty()
push() 向队尾插入一个元素
front() 返回队头元素
back() 返回队尾元素
pop() 弹出队头元素
priority_queue, 优先队列,默认是大根堆
size()
empty()
push() 插入一个元素
top() 返回堆顶元素
pop() 弹出堆顶元素
定义成小根堆的方式:priority_queue<int, vector<int>, greater<int>> q;
stack, 栈
size()
empty()
push() 向栈顶插入一个元素
top() 返回栈顶元素
pop() 弹出栈顶元素
deque, 双端队列
size()
empty()
clear()
front()/back()
push_back()/pop_back()
push_front()/pop_front()
begin()/end()
[]
set, map, multiset, multimap, 基于平衡二叉树(红黑树),动态维护有序序列
size()
empty()
clear()
begin()/end()
++, -- 返回前驱和后继,时间复杂度 O(logn)
set/multiset
insert() 插入一个数
find() 查找一个数
count() 返回某一个数的个数
erase()
(1) 输入是一个数x,删除所有x O(k + logn)
(2) 输入一个迭代器,删除这个迭代器
lower_bound()/upper_bound()
lower_bound(x) 返回大于等于x的最小的数的迭代器
upper_bound(x) 返回大于x的最小的数的迭代器
map/multimap
insert() 插入的数是一个pair
erase() 输入的参数是pair或者迭代器
find()
[] 注意multimap不支持此操作。 时间复杂度是 O(logn)
lower_bound()/upper_bound()
unordered_set, unordered_map, unordered_multiset, unordered_multimap, 哈希表
和上面类似,增删改查的时间复杂度是 O(1)
不支持 lower_bound()/upper_bound(), 迭代器的++,--
bitset, 圧位
bitset<10000> s;
~, &, |, ^
>>, <<
==, !=
[]
count() 返回有多少个1
any() 判断是否至少有一个1
none() 判断是否全为0
set() 把所有位置成1
set(k, v) 将第k位变成v
reset() 把所有位变成0
flip() 等价于~
flip(k) 把第k位取反
数学:
1.
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
return false;
return true;
}
2.
void divide(int x)
{
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
{
int s = 0;
while (x % i == 0) x /= i, s ++ ;
cout << i << ' ' << s << endl;
}
if (x > 1) cout << x << ' ' << 1 << endl;
cout << endl;
}
3.
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (st[i]) continue;
primes[cnt ++ ] = i;
for (int j = i + i; j <= n; j += i)
st[j] = true;
}
}
4.
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
5.
vector<int> get_divisors(int x)
{
vector<int> res;
for (int i = 1; i <= x / i; i ++ )
if (x % i == 0)
{
res.push_back(i);
if (i != x / i) res.push_back(x / i);
}
sort(res.begin(), res.end());
return res;
}
6.
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
__gcd(a,b)
a*b/__gcd(a,b)
7.
//m^k mod p
int qmi(int m, int k, int p)
{
int res = 1 % p, t = m;
while (k)
{
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
8.
// c[a][b] 表示从a个苹果中选b个的方案数
for (int i = 0; i < N; i ++ )
for (int j = 0; j <= i; j ++ )
if (!j) c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
9.
//组合数顶配 ,笑死
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int qmi(int a, int k, int p)
{
int res = 1;
while (k)
{
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int C(int a, int b, int p)
{
if (b > a) return 0;
int res = 1;
for (int i = 1, j = a; i <= b; i ++, j -- )
{
res = (LL)res * j % p;
res = (LL)res * qmi(i, p - 2, p) % p;
}
return res;
}
int lucas(LL a, LL b, int p)
{
if (a < p && b < p) return C(a, b, p);
return (LL)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}
int main()
{
LL a, b;
int p;
cin >> a >> b >> p;
cout << lucas(a, b, p) << endl;
return 0;
}
10.
n!中0的个数
#include <cstdio>
int main() {
int n;
scanf("%d", &n);
int ans = 0;
while (n) {
ans += n / 5;
n /= 5;
}
printf("%d", ans);
return 0;
}
高精度:
#include <iostream>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B)
{
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int t = 0;
for (int i = 0; i < A.size(); i ++ )
{
t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(t);
return C;
}
int main()
{
string a, b;
vector<int> A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
vector<int> C = add(A, B);
for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
// cout << endl;
return 0;
}
--------------------
#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector<int> &A, vector<int> &B)
{
if (A.size() != B.size()) return A.size() > B.size();
for (int i = A.size() - 1; i >= 0; i -- )
if (A[i] != B[i])
return A[i] > B[i];
return true;
}
vector<int> sub(vector<int> &A, vector<int> &B)
{
vector<int> C;
for (int i = 0, t = 0; i < A.size(); i ++ )
{
t = A[i] - t;
if (i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a, b;
vector<int> A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
vector<int> C;
if (cmp(A, B)) C = sub(A, B);
else C = sub(B, A), cout << '-';
for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
cout << endl;
return 0;
}
------------------------------------
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, int b)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || t; i ++ )
{
if (i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
auto C = mul(A, b);
for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]);
return 0;
}
----------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> div(vector<int> &A, int b, int &r)
{
vector<int> C;
r = 0;
for (int i = A.size() - 1; i >= 0; i -- )
{
r = r * 10 + A[i];
C.push_back(r / b);
r %= b;
}
reverse(C.begin(), C.end());
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a;
vector<int> A;
int B;
cin >> a >> B;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
int r;
auto C = div(A, B, r);
for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
cout << endl << r << endl;
return 0;
}
-----------------
并查集/最短路/前缀和(一维和二维)
并查集
#include<bits/stdc++.h>
using namespace std;
const int N=110;
bool root[110];
int father[110];
int findfather(int x){
int a=x;
while(x!=father[x]){
x=father[x];
}
while(a!=father[a]){
int z=a;
a=father[a];
father[z]=x;
}
return x;
}
void Union(int a,int b){
int fa=findfather(a);
int fb=findfather(b);
if(fa!=fb){
father[fa]=fb;
}
}
void init(int n){
for(int i=1;i<=n;i++){
father[i]=i;
}
}
int main(){
int n,m;
int a,b;
cin>>n>>m;
init(n);
for(int i=0;i<m;i++){
cin>>a>>b;
Union(a,b);
}
for(int i=1;i<=n;i++){
root[findfather(i)]=true;
}
int ans=0;
for(int i=1;i<=n;i++){
ans+=root[i];
}
cout<<ans<<endl;
return 0;
}
(1)朴素并查集:
int p[N]; //存储每个点的祖宗节点
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ ) p[i] = i;
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
(2)维护size的并查集:
int p[N], size[N];
//p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
size[i] = 1;
}
// 合并a和b所在的两个集合:
size[find(b)] += size[find(a)];
p[find(a)] = find(b);
(3)维护到祖宗节点距离的并查集:
int p[N], d[N];
//p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x)
{
int u = find(p[x]);
d[x] += d[p[x]];
p[x] = u;
}
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
d[i] = 0;
}
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量
-----------
floyd算法
初始化:
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (i == j) d[i][j] = 0;
else d[i][j] = INF;
// 算法结束后,d[a][b]表示a到b的最短距离
void floyd()
{
for (int k = 1; k <= n; k ++ )
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
-----------------
int g[N][N]; // 存储每条边
int dist[N]; // 存储1号点到每个点的最短距离
bool st[N]; // 存储每个点的最短路是否已经确定
// 求1号点到n号点的最短路,如果不存在则返回-1
int dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < n - 1; i ++ )
{
int t = -1; // 在还未确定最短路的点中,寻找距离最小的点
for (int j = 1; j <= n; j ++ )
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
// 用t更新其他点的距离
for (int j = 1; j <= n; j ++ )
dist[j] = min(dist[j], dist[t] + g[t][j]);
st[t] = true;
}
if (dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
----------------------------
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
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;
}
----------------
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int a[N],sum[N];
int main()
{
int n,m,x;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>x;
sum[i]=x+sum[i-1];
}
while(m--)
{
int l,r;
cin>>l>>r;
cout<<sum[r]-sum[l-1]<<endl;
}
return 0;
}
---------------
#include <iostream>
using namespace std;
const int N = 1010;
int n, m, q;
int s[N][N];
int main()
{
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
scanf("%d", &s[i][j]);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
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]);
}
return 0;
}
全排列/dfs/bfs典型入门题(能力有限)
#include <bits/stdc++.h>
using namespace std;
int main(){
string s="bca";
sort(s.begin(),s.end()); //字符串内部排序,得到最小的排列“abc”
do{
cout<<s<<endl;
}while(next_permutation(s.begin(),s.end()));
return 0;
}
--------------------------
#include<iostream>
using namespace std;
int n;
bool vis[16];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++){
if(vis[i]){
cout<<i<<" ";
}
}
cout<<"\n";
return ;
}
vis[x]=1;
dfs(x+1);
vis[x]=0;
dfs(x+1);
}
int main(){
cin>>n;
dfs(1);
return 0;
}
---------------
#include<iostream>
using namespace std;
int n;
bool vis[10];
int path[10];
void dfs(int x){
if(x>n){
for(int i=1;i<=n;i++){
cout<<path[i]<<" ";
}
cout<<"\n";
return ;
}
for(int i=1;i<=n;i++){
if(!vis[i]){
vis[i]=1;
path[i]=x;//
dfs(x+1);
vis[i]=0;
path[i]=0;//注意
}
}
}
int main(){
cin>>n;
dfs(1);
return 0;
}
---------------------
dfs
//迷宫问题(改版)
#include<iostream>
#include<string>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//移动坐标
//建议按照 逆时针 (或顺时针)方向写,方便做转头操作
bool in(int x,int y){
return 0<=x && x<n && 0<=y && y<m;
}
bool dfs(int x,int y){
//找到重点
if(maze[x][y]=='T'){
return true;
}
vis[x][y]=1;//走过了
maze[x][y]='+';//标记为+
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&maze[tx][ty]!='*'&&!vis[tx][ty]){
if(dfs(tx,ty)){
return true;
}
}
}
//走不通,取消标记
vis[x][y]=0;
maze[x][y]='.';
return false;
}
int main(){
//输入迷宫地图
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>maze[i];
}
//寻找起始点
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i,y=j;
}
}
}
//打印地图
if(dfs(x,y)){
for(int i=0;i<n;i++){
cout<<maze[i]<<endl;
}
} else {
cout<<"No!"<<endl;
}
return 0;
}
//
-----------------
bfs
#include<iostream>
#include<queue>
using namespace std;
int n,m;
char maze[105][105];
bool vis[105][105];
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//方向
bool in(int x,int y){//范围
return x>=0 && x<n && y>=0 && y<m;
}
//节点
struct node{
int x,y,d;
node(int xx,int yy,int dd){
x=xx;
y=yy;
d=dd;
}
};
int bfs(int sx,int sy){
queue<node> q;
q.push(node(sx,sy,0));
vis[sx][sy]=true;
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=now.x+dir[i][0];
int ty=now.y+dir[i][1];
if(in(tx,ty) && maze[tx][ty]!='*' && !vis[tx][ty]){
if(maze[tx][ty]=='T'){
return now.d +1;
}else{
vis[tx][ty]=true;
q.push(node(tx,ty,now.d+1));
}
}
}
}
return -1;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
}
}
int x,y;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='S'){
x=i;
y=j;
}
}
}
cout<<bfs(x,y)<<endl;
return 0;
}
/*
样例输入:
5 6
....S*
.**...
.*..*.
*..**.
.T....
样例输出:
7
*/
--------------
/*在长度为【0,n】的一维坐标中,输入A,B的地址,问能否从A到B。
移动方式:向前一步(坐标+1),向后一步(坐标-1),跳(坐标*2)*/
#include<iostream>
#include<queue>
#include<utility>
using namespace std;
bool vis[100];
int main() {
int n,A,B,now,step;
cin>>n>>A>>B;
queue< pair<int,int> >q;
q.push(make_pair(A,0));
vis[A]=true;
while(!q.empty()) {
now=q.front().first;
step=q.front().second;
q.pop();
if(now==B){
cout<<step<<endl;
break;
}
if(now+1<=n && !vis[now+1]) {
q.push(make_pair(now+1,step+1));
vis[now+1]=true;
}
if(now-1>=0 && !vis[now-1]) {
q.push(make_pair(now-1,step+1));
vis[now-1]=true;
}
if(now*2<=n && !vis[now*2]) {
q.push(make_pair(now*2,step+1));
vis[now*2]=true;
}
}
return 0;
}
/*
样例输入:
10 2 7
样例输出
3
*/
------------------------
dfs
#include<iostream>
using namespace std;
int n,k,sum,ans;
int a[100];
void dfs(int i,int cnt,int s){
if(i==n){
if(cnt==k && s==sum){
ans++;
}
return ;
}
dfs(i+1,cnt,s);//不选 a[i]
dfs(i+1,cnt+1,s+a[i]);//选 a[i]
}
int main(){
cin>>n>>k>>sum;
for(int i=0;i<n;i++){
cin>>a[i];
}
ans=0;
dfs(0,0,0);
cout<<ans<<endl;
return 0;
}
/*
输入:
5 3 9
1 2 3 4 5
输出:
2
*/
问题:
INF=-0x3f3f3f3f//
INF=0x3f3f3f3f//
string space=string(n-i,' ');//
for(vector<int>::iterator it=ve.begin();it!=ve.end();it++){
cout<<*it<<" ";
}
struct Student {
int score;
string name;
Student(){}//可是省略
Student(string name,int s) {
name=n;
score=s;
}
}
struct Student{
int score;
string name;
Student() {} //不可以省
Student(string n,int s):name(n),score(s){}
};
---------------
//最大矩阵暴力
int n,m,ans;
cin>>n>>m;
ans=-1005;//足够小
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>A[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
for(int k=0;k<m;k++){
for(int l=k;l<m;l++){
int temp=0;//代表空矩阵
for(int p=i;p<=j;p++){
for(int q=k;q<=l;q++){
temp=temp+A[p][q];
}
}
if(temp>ans){
ans=temp;
}
}
}
}
}
cout<<ans<<endl;
----------------
//最大子矩阵和
#include<iostream>
#include<cstdio>
using namespace std;
long long num[401][401];
long long presum[401][401];
int main(){
int N,M;
long long sum,ans;
cin>>N>>M;
ans=-100000;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
cin>>num[i][j];
ans=max(ans,num[i][j]);
}
}
if(ans<=0){
cout<<ans<<endl;
}else{
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
presum[i][j]=presum[i-1][j]+num[i][j];
}
}
for(int i=1;i<=N;i++){
for(int j=i;j<=N;j++){
sum=0;
for(int k=1;k<=M;k++){
if(sum+presum[j][k]-presum[i-1][k]<0){
sum=0;
}else{
sum+=presum[j][k]-presum[i-1][k];
}
ans=max(ans,sum);
}
}
}
}
cout<<ans<<endl;
return 0;
}
/*
--cin:
3 3
1 2 3
4 -5 6
7 8 9
--cout:
35
*/
-----------------
bool judge(int x){
int cnt=0;//记录位数
while(x){
digit[cnt++]=x%10;
x/=10;
}
for(int i=0;i<cnt/2;i++){
if(digit[i]!=digit[cnt-1-i]){
return false;
}
}
return true;
}
---------
#include<iostream>
using namespace std;
int dir[8][2]= {{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};
bool d[30][30];
long long dp[30][30];
int main() {
int n,m,cx,cy;// n,m棋盘大小 cx,xy马的位置
cin>>n>>m>>cx>>cy;
d[cx][cy]=true;
for(int i=0; i<8; i++) {
int tx=cx+dir[i][0];
int ty=cy+dir[i][1];
if(tx>=0 && tx<=n && ty>=0 && ty<=n) {
d[tx][ty]=true;//记录为马控制点
}
}
dp[0][0]=1;//dp[n][m]即为从(0,0)到(n,m)的路径数目
for(int i=0; i<=n; i++) {
for(int j=0; j<=m; j++) {
if(d[i][j]==false) {
if(i) {
dp[i][j]+=dp[i-1][j];
}
if(j) {
dp[i][j]+=dp[i][j-1];
}
}
}
}
cout<<dp[n][m]<<endl;
return 0;
}
/*
样例输入:
5 5 2 4
样例输出:
14
*/
-------------
//约瑟夫环
//猴子选大王 --
#include<iostream>
#include<queue>
using namespace std;
int main() {
int n,m=3;
cin>>n;
queue<int> q;
for(int i=1;i<=n;i++){
q.push(i);
}
int cur=1;
while(q.size()>1){
int x=q.front();
q.pop();
if(cur!=m){
q.push(x);
cur++;
} else{
cur=1;
}
}
cout<<q.front()<<endl;
}
------------
//二进制优化版本
#include<iostream>
using namespace std;
const int N = 12010, M = 2010;
int n, m;
int v[N], w[N]; //逐一枚举最大是N*logS
int f[M]; // 体积<M
int main()
{
cin >> n >> m;
int cnt = 0; //分组的组别
for(int i = 1;i <= n;i ++)
{
int a,b,s;
cin >> a >> b >> s;//v体积 w价值 s数量
int k = 1; // 组别里面的个数
while(k<=s)
{
cnt ++ ; //组别先增加
v[cnt] = a * k ; //整体体积
w[cnt] = b * k; // 整体价值
s -= k; // s要减小
k *= 2; // 组别里的个数增加
}
//剩余的一组
if(s>0)
{
cnt ++ ;
v[cnt] = a*s;
w[cnt] = b*s;
}
}
n = cnt ; //枚举次数正式由个数变成组别数
//01背包一维优化
for(int i = 1;i <= n ;i ++)
for(int j = m ;j >= v[i];j --)
f[j] = max(f[j],f[j-v[i]] + w[i]);
cout << f[m] << endl;
return 0;
}
接下来最后总结一下dp(背典型)`
三包tmd
---------------
01背包 (二维)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int v[MAXN]; // 体积
int w[MAXN]; // 价值
int dp[MAXN][MAXN]; // f[i][j], j体积下前i个物品的最大价值
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++)
cin >> v[i] >> w[i];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
// 当前背包容量装不进第i个物品,则价值等于前i-1个物品
if(j < v[i])
dp[i][j] = dp[i - 1][j];
// 能装,需进行决策是否选择第i个物品
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
}
cout << dp[n][m] << endl;
return 0;
}
01背包(一维)
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int f[N];
int v[N], w[N];
int n, m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];
for (int i = 1; i <= n; i++) {
for (int j = m; j >= v[i]; j--) {
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
}
cout << f[m] << endl;
}
--------------------
多重背包(二维度)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e2+10;
int f[N][N],w[N],v[N],s[N];
int main()
{
int n,V;
cin>>n>>V;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i]>>s[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<=V;j++)
{
for(int k=0;k<=s[i];k++)
{
if(k*v[i]<=j) f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
}
}
cout<<f[n][V];
return 0;
}
多重背包(一维)
#include <bits/stdc++.h>
using namespace std;
int N, V, u,w, s, f[10500];
int main() {
cin >> N >> V;
for (int i = 0; i < N; i++) {
cin >> u >> w >> s;
for (int j = V; j >= u; j--)
for (int k = 1; k <= s; k++) {
if (j >= k * u)
f[j] = max(f[j], f[j - k * u] + k * w);
else
break;
}
}
cout << f[V] << endl;
return 0;
}
----------------------
完全背包(二维)
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int f[1010][1010];
int v[1010],w[1010];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&v[i],&w[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
f[i][j]=f[i-1][j];
if(j>=v[i])
{
f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);
}
}
}
printf("%d\n",f[n][m]);
return 0;
}
完全背包(一维)
#include<iostream>
using namespace std;
const int N = 1010;
int n, m;
int dp[N];
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i ++ ){
int v, w;
cin >> v >> w;
for(int j = v; j <= m; j ++ ){
dp[j] = max(dp[j], dp[j - v] + w);
}
}
cout << dp[m] << endl;
}
典型案例:
--------------
//数字三角形
#include<bits/stdc++.h>
using namespace std;
const int N=510,INF=0x3f3f3f3f;
int f[N][N];
int a[N][N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<=i+1;j++){ //因为有负数,所以应该将两边也设为-INF
f[i][j]=-INF;
}
}
f[1][1]=a[1][1];
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
f[i][j]=a[i][j]+max(f[i-1][j-1],f[i-1][j]);
}
}
int res=-INF;
for(int i=1;i<=n;i++) res=max(res,f[n][i]);
cout<<res<<endl;
}
----------------
//最大连续子序列和
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
int a[n], dp[n] = { 0 };
for (int i = 0 ; i < n; i++)
{
scanf("%d", &a[i]);
}
dp[0] = a[0];
int ans = -0x3f3f3f3f;
for (int i = 0; i < n; i++)
{
dp[i] = max(a[i], dp[i - 1] + a[i]);
ans = max(dp[i], ans);
}
printf("%d\n", ans);
return 0;
}
--------------------
//最长上升"子序列"(不连续)
#include<iostream>
#include<cstdio>
using namespace std;
int n,a[105],dp[105];
int ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
dp[i]=1;
for(int j=1;j<i;j++){
if(a[j]<a[i]){
dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
return 0;
}
/*
cin:
8
2 1 5 3 6 4 6 3
cout:
4
*/
---------------
//最长公共子序列
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int dp[110][110];
int main()
{
string a, b;
memset(dp, 0, sizeof(dp));
cin >> a >> b;
int lena = a.size();
int lenb = b.size();
for (int i = 1; i <= lena; i++)
{
for (int j = 1; j <= lenb; j++)
{
if (a[i - 1] == b[j - 1])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
cout << dp[lena][lenb] << endl;
return 0;
}
-------------