代码算法.docx
- 文档编号:28740960
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:66
- 大小:32.46KB
代码算法.docx
《代码算法.docx》由会员分享,可在线阅读,更多相关《代码算法.docx(66页珍藏版)》请在冰豆网上搜索。
代码算法
目录
一、卡特兰数-1-
二、二分图-2-
三、高斯消元-3-
四、黑白棋反转,异或,二进制,BFS-7-
五、K-number-8-
六、R^n-10-
七、DP辩控-11-
八、包装盒的个数-16-
九、青蛙约会-17-
十、DFS昂贵的聘礼-18-
十一、着色问题-19-
十二、八皇后问题-21-
十三、全排列-22-
十四、数学公式-24-
十五、约瑟夫环-24-
十六、最短路径-24-
十七、Manacher算法一个字符串里面最长回文数长度-26-
十八、并查集-27-
十九、凸包算法-28-
二十、单峰回文数dp-29-
二十一、威佐夫博奕-30-
二十二、汉诺塔-31-
一、卡特兰数
/*
题意:
给你n个结点,则有C(2n,n)/(n+1)种二叉树,而不同结点又有n!
种
所以最后N=C(2n,n)/(n+1)*n!
SampleInput
1
2
10
25
0
SampleOutput
1
4
60949324800
75414671852339208296275849248768000000
*/
#include
#include
usingnamespacestd;
voidmul(vector
{
inti,tmp;
for(i=0;i { v[i]*=p; } for(i=0;i { v[i+1]+=v[i]/10; v[i]%=10; } while(v[i]>=10)//最后一位要注意当v[i]是三位数或者更多位,需要连续进位 { v.push_back(v[i]/10); v[i]%=10; i++; } } voiddiv(vector { inti; for(i=v.size()-1;i>0;i--) { v[i-1]+=v[i]%p*10; v[i]/=p; } v[0]/=p; } intmain() { vector intn; inti; while(cin>>n&&n! =0) { vec.clear(); vec.push_back (1); for(i=1;i { mul(vec,i+1);//n! 阶乘 mul(vec,(4*i+2));//卡塔兰数 div(vec,i+2); } i=vec.size()-1; while(vec[i]==0) { i--; } while(i>=0) { cout< } cout< } return0; } 二、二分图 性质: 最大匹配数=最小覆盖数 最大独立数=最大匹配数 ⏹最小路径覆盖数=顶点数n-最大匹配数 /* 有n门课程有m个学生选,每门课要一个学生作代表,问是否能够 是每个人选的课,而不是每个课选的人 */ #include usingnamespacestd; intmap[301][301]; intpoint[301]; boolvis[301]; intn,p; boolf(intx) { inty; for(y=1;y<=n;y++) { if(map[x][y]==1&&vis[y]==false) { vis[y]=true; if(point[y]==0||f(point[y])) { point[y]=x; returntrue; } } } returnfalse; } intmain() { intx,y,i,j,cases,r; cin>>cases; while(cases--) { cin>>p>>n; memset(map,0,sizeof(map)); memset(point,0,sizeof(point)); r=0; for(i=1;i<=p;i++) { cin>>x; for(j=0;j { cin>>y; map[i][y]=1; } } for(i=1;i<=p;i++) { memset(vis,false,sizeof(vis)); if(f(i))///匹配 r++; } if(r==p) cout<<"YES"< else cout<<"NO"< } return0; } 三、高斯消元 /* 将输入的数组,全部变成y SampleInput 2 3 yyy yyy yyy 5 wwwww wwwww wwwww wwwww wwwww SampleOutput 0 15 */ #include #include #include usingnamespacestd; intmap1[230][230],ans,n,m; intdir[4][2]={0,1,0,-1,1,0,-1,0}; intgauss(){ inti,j,k,t; for(i=0,j=0;i k=i; while(! map1[k][j]&&k k++; if(k==n){ i--;continue; } if(k! =i) for(t=j;t<=n;t++)//交换k行和t行 swap(map1[i][t],map1[k][t]); for(k=i+1;k if(map1[k][j]) for(t=j;t<=n;t++) map1[k][t]^=map1[i][t]; } k=i; for(i=k;i if(map1[i][n]) return-1; for(i=k-1,t=0;i>=0;i--){ for(j=i+1;j map1[i][n]^=(map1[i][j]&&map1[j][n]); if(map1[i][n])t++; } returnt; } intmain(){ intcas,i,j,ans; charc; scanf("%d",&cas); while(cas--){ scanf("%d",&m); memset(map1,0,sizeof(map1)); n=m*m; for(i=0;getchar(),i for(j=0;j c=getchar(); if(c=='w') map1[i*m+j][n]=1; else map1[i*m+j][n]=0; } for(i=0;i for(j=0;j map1[i*m+j][i*m+j]=1; for(intk=0;k<4;k++){ intdx=i+dir[k][0],dy=j+dir[k][1]; if(dx>=0&&dx map1[dx*m+dy][i*m+j]=1; } } ans=gauss(); if(ans==-1) printf("inf\n"); else printf("%d\n",ans); } return0; } /* SampleInput 2 011010 100111 001001 100101 011100 001010 101011 001011 101100 010100 SampleOutput PUZZLE#1 101001 110101 001011 100100 010000 PUZZLE#2 100111 110000 000100 110101 101101 */ #include #include #include usingnamespacestd; #defineMAXN30 inta[MAXN][MAXN],b[MAXN]; intGauss(intn,inta[][MAXN],intb[]) { inti,j,k,row; for(k=0;k { for(i=k;i if(a[i][k]==1){row=i;break;} if(i==n)return0;//由于控制矩阵可逆,所以x[]是有唯一解的,此处也可省略 if(row! =k) { for(j=k;j swap(a[k][j],a[row][j]); swap(b[k],b[row]); } for(i=k+1;i { if(a[i][k]==0)continue;//按行处理 for(j=k+1;j a[i][j]^=a[k][j]; b[i]^=b[k]; } } b[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { for(j=i+1;j b[i]^=(a[i][j]*b[j]); b[i]=b[i]/a[i][i]; } return1; } voidinit() { inti,j; intt1,t2,t3,t4; for(i=0;i<30;i++) { t1=i/6; t2=i%6; for(j=0;j<30;j++) { t3=j/6; t4=j%6; if(abs(t1-t3)+abs(t2-t4)<=1) a[i][j]=1; elsea[i][j]=0; } } } intmain() { intt,k,i; scanf("%d",&t); for(k=1;k<=t;k++) { for(i=0;i<30;i++) scanf("%d",&b[i]); init(); Gauss(30,a,b); printf("PUZZLE#%d\n",k); for(i=1;i<=30;i++) { printf("%d",b[i-1]); if(i%6==0)printf("\n"); } } return0; } 四、黑白棋反转,异或,二进制,BFS /* 黑白棋子反转成同一颜色 SampleInput bwwb bbwb bwwb bwww SampleOutput 4 */ #include #include usingnamespacestd; #defineMAXN65536 intque[MAXN*2]; intfront,rear; boolused[MAXN]; intstep[MAXN]; boolfind0; voidbfs(intp) { find0=false; step[p]=0; if(p==0||p==65535) { cout<<"0"< find0=true; return; } memset(used,false,sizeof(used)); memset(que,0,sizeof(que)); memset(step,0,sizeof(step)); rear=front=0; que[rear++]=p; used[p]=true; while(rear>front) { inttmp=que[front++]; intt=tmp; for(inti=0;i<16;i++) { tmp=t; tmp^=1<<(15-i);//第i位本身取反 if(i%4==0)tmp^=1<<(14-i);//只有左边 elseif(i%4==3)tmp^=1<<(16-i);//只有右边 elsetmp^=5<<(14-i);//两边都有 if(i<=3)tmp^=1<<(15-4-i);//只有下边 elseif(i>=12)tmp^=1<<(15+4-i);//只有上边 else { tmp^=1<<(15-4-i); tmp^=1<<(15+4-i); } if(tmp==0||tmp==65535) { cout< find0=true; return; } if(used[tmp]==false) { que[rear++]=tmp; used[tmp]=true; step[tmp]=step[t]+1; } } } } intmain() { inti; charcolor; intid; id=0; for(i=0;i<15;i++) { cin>>color; id<<=1; if(color=='b')id+=1; } cin>>color; if(color=='b')id+=1; bfs(id); if(find0==false) { cout<<"Impossible"< } return0; } 五、K-number /* K-thNumber SampleInput 73 1526374 253 441 173 SampleOutput 5 6 3 */ #include #include usingnamespacestd; #defineMAXN20+5 #defineLOGMAXN17+5 intsortseq[LOGMAXN][MAXN],n,q,key[MAXN],s,t,rk; structNode { intl,r; }nod[3*MAXN]; voidbuildtree(intu,intl,intr,intdeep) { inti,j,m,loop; nod[u].l=l; nod[u].r=r; if(l==r){ sortseq[deep][l]=key[l]; return; } m=(l+r)/2; buildtree(2*u,l,m,deep+1); buildtree(2*u+1,m+1,r,deep+1); i=l;j=m+1;loop=l; while(i<=m&&j<=r){ if(sortseq[deep+1][i] sortseq[deep][loop++]=sortseq[deep+1][i++]; else sortseq[deep][loop++]=sortseq[deep+1][j++]; } if(i==m+1) while(j<=r) sortseq[deep][loop++]=sortseq[deep+1][j++]; else while(i<=m) sortseq[deep][loop++]=sortseq[deep+1][i++]; } intquery(intu,intval,intdeep){//找到一个区间[nod[u].r,nod[u].l]是区间[s,t]的子区间然后判断val是第几大 if(s<=nod[u].l&&nod[u].r<=t) { inttmp=lower_bound(&sortseq[deep][nod[u].l],&sortseq[deep][nod[u].r]+1,val)-&sortseq[deep][nod[u].l]; returntmp;//lower_bound()返回一个iterator它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于value的值。 } intres=0; if(s<=nod[2*u].r) res+=query(2*u,val,deep+1); if(t>=nod[2*u+1].l) res+=query(2*u+1,val,deep+1); returnres; } intmain(){ inti,l,r,m,pos; inttt; scanf("%d",&tt); while(tt--) { while(scanf("%d%d",&n,&q)! =EOF) { for(i=1;i<=n;i++) scanf("%d",&key[i]); buildtree(1,1,n,1); while(q--) { scanf("%d%d%d",&s,&t,&rk); rk--;//* l=1;r=n; while(l { m=(l+r+1)/2;//* pos=query(1,sortseq[1][m],1); if(pos<=rk) l=m; else r=m-1; } printf("%d\n",sortseq[1][l]); } } } return0; } 六、R^n #include #include #include usingnamespacestd; intmain() { strings; inta[1000],b[1000]; intn,l,i,j,p,lb; while(cin>>s>>n) { l=s.length(); for(i=l-1;i>=0;i--) { if(s[i]=='0') l--; elsebreak; } if(l==0){cout<<"0"< if(s.find('.',0)! =string: : npos) { p=l-1-s.find('.',0);//小数点位数 s.erase(s.begin()+s.find('.',0));//移除小数点 p*=n,l--; } elsep=0; for(i=l-1;i>=0;i--) a[l-1-i]=b[l-1-i]=s[i]-'0'; n--,lb=l; while(n--) { intr[1000]={0}; for(i=0;i for(j=0;j r[i+j]+=a[i]*b[j]; for(i=0;i { r[i+1]+=r[i]/10; b[i]=r[i]%=10; } lb+=l; } while(b[lb-1]==0) lb--; if(lb>0) { if(lb-1 { cout<<"."; for(i=0;i cout<<"0"; } for(i=lb-1;i>=0;i--) { cout< if(p&&i==p) cout<<"."; } } elsecout<<"0"< cout< } return0; } 七、DP辩控 /* 解题思路: 用dp[i][j]保存辩控和,j表示辩控差,i表示选了几个候选人。 那么已知dp[0][0]=0,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 代码 算法