ACM常用模板 大数(整数类封装)

合集下载

数据结构ACM模板

数据结构ACM模板

<数据结构>闭散列法整数hash#define max 4000037int hash[max],c[max];//hash存关键字,c存该位置关键字出现的次数bool use[max];int n,m,ans;int k[6],p[6];int locate(int k)//hash函数{int tmp;tmp = k;while(tmp<0)tmp+=max;while(tmp>=max)tmp-=max;while(use[tmp]&&hash[tmp]!=k){tmp++;if(tmp>=max)tmp-=max;}return tmp;}void insert(int k){int pos = locate(k);hash[pos] = k;use[pos] = 1;c[pos]++;}int onlyfind(int k){int pos = locate(k);if(hash[pos]==k)return c[pos];else return -1;}整数hash,开散列#include <stdio.h>#include <memory.h>#define MAX 3400000#define M 28999999int head[M],next[MAX];int lkey[MAX],up,ans;int n,m;int k[6],p[6];int hash(int key){int h;//h = ((key>>16)&&key)^(key>>8);h = ((~key)>>8)&&key ||( (key<<16) );h%=M;return h;}int find(int key){int h,p;h = hash(key);for(p=head[h];p>=0;p=next[p])if(lkey[p]==key)return 1;lkey[up] = key;next[up] = head[h];head[h] = up++;return -1;}int onlyfind(int key){int h,p;h = hash(key);for(p=head[h];p>=0;p=next[p])if(lkey[p]==key)return 1;return -1;}字符串hashint ELFhash(char *key) {unsigned h=0;while(*key) {h=(h<<4) + *key++;unsigned g=h & 0Xf0000000L;if(g) h^=g>>24;h &= ~g;}return h% M;}堆int heap[MAX+1],heapsize;void push(int key){int pos;pos = ++heapsize;while(pos>0&&heap[pos>>1]>key){heap[pos] = heap[pos>>1];pos>>=1;}heap[pos] = key;}void pop(){int key = heap[heapsize--];int pos,npos;pos = 1;npos = pos<<1;while(npos<=heapsize){if(npos+1<=heapsize&&heap[npos+1]<heap[npos])npos+=1;if(heap[npos]>=key)break;heap[pos] = heap[npos];pos = npos;npos = pos<<1;}heap[pos] = key;}二维树状数组int lowbit(int x){return x&(-x);}void updata(int x,int y,int w){int i,j;for(i=x;i<=n;i+=lowbit(i)){for(j=y;j<=n;j+=lowbit(j)){c[i][j]+=w;}}}int sum(int x,int y){int t=0,i,j;for(i=x;i>0;i-=lowbit(i)){for(j=y;j>0;j-=lowbit(j)){t+=c[i][j];}}return t;}Trie树#include<iostream>#define keyNum 26#define MaxN 50struct trie...{struct trieNode...{//trie结点的结构trieNode *link[keyNum];//下标为 'A' , 'B' , 'C' , , 'Z' 的指针数组 int num[keyNum];//插入key的次数trieNode()...{memset(num,0,sizeof(num));memset(link,NULL,sizeof(link));}void init()...{memset(link,NULL,sizeof(link));memset(num,0,sizeof(num));}};trieNode* root;trie()...{root=(trieNode*)malloc(sizeof(trieNode));//初始化时为root申请了空间 root->init();}bool Search(char *);void Insert(char []);void Delete(trieNode*);};bool trie::Search(char * x)...{if(*x==0)return false;trieNode* current=root;x++;while(*x)...{if(current->link[*(x-1)-'a'])current=current->link[*(x-1)-'a'];else break;x++;}if(*x==0&&current->num[*(x-1)-'a'])return true;else return false;}void trie::Delete(trieNode* t)...{int i;for(i=0;i<keyNum;i++)if(t->link[i])Delete(t->link[i]);memset(t->num,0,sizeof(t->num));delete(t);}void trie::Insert(char x[])...{trieNode *current=root;int i=1;while(x[i])...{if(current->link[x[i-1]-'a']==NULL)...{current->link[x[i-1]-'a']=(trieNode*)malloc(sizeof(trieNode)); (current->link[x[i-1]-'a'])->init();}current=current->link[x[i-1]-'a'];i++;}(current->num[x[i-1]-'a'])++;}char c[ 50000 ][MaxN],tmp;int main()...{trie a;int i=0,j,num;while(scanf("%s",c[i])!=EOF)a.Insert(c[i++]);num=i;for(i=0;i<num;i++)for(j=1;c[i][j];j++)...{tmp=c[i][j];c[i][j]=0;if(a.Search(c[i]))...{c[i][j]=tmp;if(a.Search(&c[i][j]))...{ printf("%s ",c[i]);break;}}else c[i][j]=tmp;}a.Delete(a.root);return 0;}二叉查找树//key是字符串#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct BiTNode{char data[31];struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;BiTree p=NULL;void InorderBST(BiTree T){if(T->lchild) InorderBST(T->lchild);printf("%s\n",T->data);if(T->rchild) InorderBST(T->rchild);}int SearchBST(BiTree T,char key[],BiTree f){int tmp1,tmp2;tmp1=tmp2=0;if(!T) {p=f;return 0;}\\找不到返回路径上最后一点else if(!strcmp(key,T->data)) {p=T;return 1;}else if(strcmp(key,T->data)<0) tmp1=SearchBST(T->lchild,key,T); else tmp2=SearchBST(T->rchild,key,T);if(tmp1||tmp2) return 1;else return 0;}BiTree InsertBST(BiTree T,char e[]){BiTree s;if(!SearchBST(T,e,NULL))//查找不到,(若已经存在则放弃){s=(BiTree)malloc(sizeof(BiTNode));strcpy(s->data,e);s->lchild=s->rchild=NULL;if(!p) return s;else{if(strcmp(e,p->data)<0) p->lchild=s;else p->rchild=s;}}//else //若出现过做相应处理}/*int main(){BiTree T=NULL;char key[31];while(gets(key)!=NULL){if(T==NULL)T=InsertBST(T,key);//空树将返回指向根节点的指针else InsertBST(T,key);}InorderBST(T);return 0;}*/线段树#include<stdio.h>#include<memory.h>#define MAX 100001int up;int count[31];struct NODE{int l,r,flag;NODE *lcd,*rcd;void build(int i,int j);void insert(int i,int j,int k);void get(int i,int j);}node[MAX*4],*root=&node[0];void NODE::build(int i,int j){l=i;r=j;flag=1;if(l==r){lcd=rcd=NULL;}else{lcd=&node[up++];rcd=&node[up++];lcd->build(l,(l+r)/2);rcd->build((l+r)/2+1,r);}}void NODE::insert(int i,int j,int k) {if(i>r||j<l)return;if(i<=l&&j>=r){flag=k;return;}else{if(flag!=-1){lcd->insert(l,r,flag);rcd->insert(l,r,flag);}lcd->insert(i,j,k);rcd->insert(i,j,k);flag=-1;}}void NODE::get(int i,int j){if(i>r||j<l)return;if(flag!=-1){count[flag]=1;}else{lcd->get(i,j);rcd->get(i,j);}}int main(){int l,t,o,i,j,k,ans;char s[5];// freopen("in.txt","r",stdin);scanf("%d%d%d",&l,&t,&o);up=1;root->build(1,l);while(o--){scanf("%s",s);if(s[0]=='C'){scanf("%d%d%d",&i,&j,&k);root->insert(i,j,k);}else{scanf("%d%d",&i,&j);memset(count,0,sizeof(count));root->get(i,j);ans=0;for(i=1;i<=t;i++){if(count[i]){ans++;}}printf("%d\n",ans);}}return 0;}线段树动态运用#include<stdio.h>#include<memory.h>#include<algorithm>using namespace std;#define MAXN 1000001#define MAXM 50001int value[MAXN],dog[MAXN],b[MAXM],e[MAXM],rank[MAXM],ans[MAXM],ind[MAXM]; int up=1;struct NODE{int now,count;NODE *rcd,*lcd;void build(int i,int j);void insert(int key);void dele(int key);int get(int k);}node[MAXN*4],*root=&node[0];bool cmp(int p,int q){return b[p]<b[q]||b[p]==b[q]&&e[p]<e[q];}void NODE::build(int i,int j){now=(i+j)/2;if(i==j){lcd=rcd=NULL;}else{lcd=&node[up++];rcd=&node[up++];lcd->build(i,(i+j)/2);rcd->build((i+j)/2+1,j);}}void NODE::insert(int key){count++;if(lcd==NULL)return;if(key<=value[now]){lcd->insert(key);}else{rcd->insert(key);}}void NODE::dele(int key){count--;if(lcd==NULL)return;if(key<=value[now]){lcd->dele(key);}else{rcd->dele(key);}}int NODE::get(int k){if(lcd==NULL)return value[now];if(lcd->count>=k){return lcd->get(k);}else{return rcd->get(k-lcd->count);}}int main(){int n,m,i,j;// freopen("d:/in.txt","r",stdin);scanf("%d%d",&n,&m);for(i=0;i<n;i++){scanf("%d",&dog[i]);value[i]=dog[i];}sort(value,value+n);n=unique(value,value+n)-value;root->build(0,n-1);for(i=0;i<m;i++){scanf("%d%d%d",&b[i],&e[i],&rank[i]);b[i]--;e[i]--;ind[i]=i;}sort(ind,ind+m,cmp);for(i=b[ind[0]];i<=e[ind[0]];i++){root->insert(dog[i]);}ans[ind[0]]=root->get(rank[ind[0]]);for(i=1;i<m;i++){for(j=b[ind[i-1]];j<b[ind[i]];j++){root->dele(dog[j]);}for(j=e[ind[i-1]]+1;j<=e[ind[i]];j++){root->insert(dog[j]);}ans[ind[i]]=root->get(rank[ind[i]]);}for(i=0;i<m;i++){printf("%d\n",ans[i]);}return 0;}RMQvoid RMQ(int M[MAXN][LOGMAXN], int A[MAXN], int N){int i, j;//initialize M for the intervals with length 1for (i = 0; i < N; i++)M[i][0] = i;//compute values from smaller to bigger intervalsfor (j = 1; 1 << j <= N; j++)for (i = 0; i + (1 << j) - 1 < N; i++)if (A[M[i][j - 1]] < A[M[i + (1 << (j - 1))][j - 1]]) M[i][j] = M[i][j - 1];elseM[i][j] = M[i + (1 << (j - 1))][j - 1];}//产生的M[i][j]为[ i , j ]中最小的数//查询:[ l , r ]//k:=ln((r-l+1)/ln(2)); ans:=min(M[l,k],M[r-2^k+1,k]);LCA+RMQ#include <stdio.h>#include <math.h>#include <memory.h>#define MAX 1000int tree[MAX][MAX],first[MAX];int len[MAX],count[MAX];int node[2*MAX],deep[2*MAX],top;int M[MAX][32],in[MAX];int N;void dfs(int u,int pre,int d){int i,t;node[top] = u;deep[top] = d;if(first[u]==-1)first[u] = top;top++;for(i=0;i<len[u];i++){t = tree[u][i];if(pre==t)continue;dfs(t,u,d+1);node[top] = u;deep[top] = d;top++;}}void RMQ_init(){int i,j;for(i=0;i<top;i++)M[i][0] = i;for(j=1;(1<<j)<=top;j++)for(i=0;i+(1<<j)-1<top;i++)if(deep[M[i][j-1]]<deep[M[i+(1<<(j-1))][j-1]]) M[i][j] = M[i][j-1];elseM[i][j] = M[i+(1<<(j-1))][j-1];}int RMQ_query(int u,int v){int l,r,t;l = first[u];r = first[v];if(l>r){t = l;l = r;r = t;}t = log((double)(r-l+1))/log(2.0);if(deep[M[l][t]]<=deep[M[r-(1<<t)+1][t]]) return node[M[l][t]];elsereturn node[M[r-(1<<t)+1][t]];}int main(){//freopen("in.txt","r",stdin);int i,u,v,k,j,T,s;char ch;while(scanf("%d",&N)!=EOF){memset(len,0,sizeof(len));memset(in,0,sizeof(in));for(i=1;i<=N;i++){scanf("%d",&u);while((ch=getchar())!=':');while((ch=getchar())!='(');scanf("%d",&k);while((ch=getchar())!=')');for(j=1;j<=k;j++){scanf("%d",&v);in[v]++;tree[u][len[u]++] = v;//tree[v][len[v]++] = u;}}top = 0;memset(first,-1,sizeof(first));for(i=1;i<=N;i++)if(in[i]==0){s = i;break;}dfs(s,-1,0);RMQ_init();scanf("%d",&T);memset(count,0,sizeof(count));for(i=1;i<=T;i++){while((ch=getchar())!='(');scanf("%d%d",&u,&v);while((ch=getchar())!=')');s = RMQ_query(u,v);count[s]++;}for(i=1;i<=N;i++)if(count[i]>0)printf("%d:%d\n",i,count[i]);}return 0;}SB-Tree#include <stdio.h>int n,f;void solve(int a,int b,int c,int d){ //0,1,1,1if (b+d>n) return;solve(a,b,a+c,b+d);if(f){printf("%d/%d",a+c,b+d);f=0;}elseprintf(",%d/%d",a+c,b+d);solve(a+c,b+d,c,d);};int main(){int T;scanf("%d",&T);while(T--){scanf("%d",&n);f=1;solve(0,1,1,1);printf("\n");}return 0;}。

[IT计算机]山东大学ACM模板_图论

[IT计算机]山东大学ACM模板_图论

图论1.最短路径 (4)1)Dijkstra之优雅stl (4)2)Dijkstra__模拟数组 (4)3)Dijkstra阵 (5)4)SPFA优化 (6)5)差分约束系统 (7)2.K短路 (7)1)Readme (7)2)K短路_无环_Astar (7)3)K短路_无环_Yen (10)4)K短路_无环_Yen_字典序 (12)5)K短路_有环_Astar (15)6)K短路_有环_Yen (17)7)次短路经&&路径数 (20)3.连通分支 (21)1)图论_SCC (21)2)2-sat (23)3)BCC (25)4.生成树 (27)1)Kruskal (27)2)Prim_MST是否唯一 (28)3)Prim阵 (29)4)度限制MST (30)5)次小生成树 (34)6)次小生成树_阵 (36)7)严格次小生成树 (37)8)K小生成树伪代码 (41)9)MST计数_连通性状压_NOI07 (41)10)曼哈顿MST (43)11)曼哈顿MST_基数排序 (46)12)生成树变MST_sgu206 (49)13)生成树计数 (52)14)最小生成树计数 (53)15)最小树形图 (56)16)图论_最小树形图_double_poj3壹64 (58)5.最大流 (60)1)Edmonds_Karp算法 (60)2)SAP邻接矩阵 (61)3)SAP模拟数组 (62)4)SAP_BFS (63)5)sgu壹85_AC(两条最短路径) (64)6)有上下界的最大流—数组模拟 (67)6.费用流 (69)1)费用流_SPFA_增广 (69)2)费用流_SPFA_消圈 (70)3)ZKW数组模拟 (72)7.割 (73)1)最大权闭合图 (73)2)最大密度子图 (73)3)二分图的最小点权覆盖 (74)4)二分图的最大点权独立集 (75)5)无向图最小割_Stoer-Wagner算法 (75)6)无向图最大割 (76)7)无向图最大割(壹6ms) (76)8.二分图 (78)1)二分图最大匹配Edmonds (78)2)必须边 (79)3)最小路径覆盖(路径不相交) (79)4)二分图最大匹配HK (80)5)KM算法_朴素_O(n4) (81)6)KM算法_slack_O(n3) (82)7)点BCC_二分判定_(2942圆桌骑士) (84)8)二分图多重匹配 (86)9)二分图判定 (88)10)最小路径覆盖(带权) (89)9.一般图匹配 (90)1)带花树_表 (90)2)带花树_阵 (93)10.各种回路 (96)1)CPP_无向图 (96)2)TSP_双调欧几里得 (97)3)哈密顿回路_dirac (98)4)哈密顿回路_竞赛图 (100)5)哈密顿路径_竞赛图 (102)6)哈密顿路径_最优&状压 (102)11.分治树 (104)1)分治树_路径不经过超过K个标记节点的最长路径 (104)2)分治树_路径和不超过K的点对数 (107)3)分治树_树链剖分_Count_hnoi壹036 (109)4)分治树_QTree壹_树链剖分 (113)5)分治树_POJ3237(QTree壹升级)_树链剖分 (117)6)分治树_QTree2_树链剖分 (122)7)Qtree3 (125)8)分治树_QTree3(2)_树链剖分 (128)9)分治树_QTree4_他人的 (130)10)分治树_QTree5_无代码 (135)12.经典问题 (135)1)欧拉回路_递归 (135)2)欧拉回路_非递归 (136)3)同构_树 (137)4)同构_无向图 (140)5)同构_有向图 (141)6)弦图_表 (143)7)弦图_阵 (147)8)最大团_朴素 (149)9)最大团_快速 (149)10)极大团 (150)11)havel定理 (151)12)Topological (151)13)LCA (152)14)LCA2RMQ (154)15)树中两点路径上最大-最小边_Tarjan扩展 (157)16)树上的最长路径 (160)17)floyd最小环 (161)18)支配集_树 (162)19)prufer编码_树的计数 (164)20)独立集_支配集_匹配 (165)21)最小截断 (168)最短路径Dijkstra之优雅stl#include <queue>using namespace std;#define maxn 壹000struct Dijkstra {typedef pair<int, int> T; //first: 权值,second: 索引vector<T> E[maxn]; //边int d[maxn]; //最短的路径int p[maxn]; //父节点priority_queue<T, vector<T>, greater<T> > q;void clearEdge() {for(int i = 0; i < maxn; i ++)E[i].clear();}void addEdge(int i, int j, int val) {E[i].push_back(T(val, j));}void dijkstra(int s) {memset(d, 壹27, sizeof(d));memset(p, 255, sizeof(p));while(!q.empty()) q.pop();int u, du, v, dv;d[s] = 0;p[s] = s;q.push(T(0, s));while (!q.empty()) {u = q.top().second;du = q.top().first;q.pop();if (d[u] != du) continue;for (vector<T>::iterator it=E[u].begin();it!=E[u].end(); it++){ v = it->second;dv = du + it->first;if (d[v] > dv) {d[v] = dv;p[v] = u;q.push(T(dv, v));}}}}};Dijkstra__模拟数组typedef pair<int,int> T;struct Nod {int b, val, next;void init(int b, int val, int next) {th(b); th(val); th(next);}};struct Dijkstra {Nod buf[maxm]; int len; //资源int E[maxn], n; //图int d[maxn]; //最短距离void init(int n) {th(n);memset(E, 255, sizeof(E));len = 0;}void addEdge(int a, int b, int val) {buf[len].init(b, val, E[a]);E[a] = len ++;}void solve(int s) {static priority_queue<T, vector<T>, greater<T> > q;while(!q.empty()) q.pop();memset(d, 63, sizeof(d));d[s] = 0;q.push(T(0, s));int u, du, v, dv;while(!q.empty()) {u = q.top().second;du = q.top().first;q.pop();if(du != d[u]) continue;for(int i = E[u]; i != -壹; i = buf[i].next) {v = buf[i].b;dv = du + buf[i].val;if(dv < d[v]) {d[v] = dv;q.push(T(dv, v));}}}}};Dijkstra阵//Dijkstra邻接矩阵,不用heap!#define maxn 壹壹0const int inf = 0x3f3f3f3f;struct Dijkstra {int E[maxn][maxn], n; //图,须手动传入!int d[maxn], p[maxn]; //最短路径,父亲void init(int n) {this->n = n;memset(E, 63, sizeof(E));}void solve(int s) {static bool vis[maxn];memset(vis, 0, sizeof(vis));memset(d, 63, sizeof(d));memset(p, 255, sizeof(p));d[s] = 0;while(壹) {int u = -壹;for(int i = 0; i < n; i ++) {if(!vis[i] && (u==-壹||d[i]<d[u])) {u = i;}}if(u == -壹 || d[u]==inf) break;vis[u] = true;for(int v = 0; v < n; v ++) {if(d[u]+E[u][v] < d[v]) {d[v] = d[u]+E[u][v];p[v] = u;}}}}} dij;SPFA优化/*** 以下程序加上了vis优化,但没有加slf和lll优化(似乎效果不是很明显)* 下面是这两个优化的教程,不难实现----------------------------------SPFA的两个优化该日志由 zkw 发表于 2009-02-壹3 09:03:06SPFA 与堆优化的 Dijkstra 的速度之争不是一天两天了,不过从这次 USACO 月赛题来看,SPFA 用在分层图上会比较慢。

ACM常用算法模板

ACM常用算法模板

专用模板目录:一、图论1.最大团2.拓扑排序3.最短路和次短路4.SAP模板5.已知各点度,问能否组成一个简单图6.KRUSKAL7. Prim算法求最小生成树8. Dijkstra9 . Bellman-ford10. SPFA11. Kosaraju 模板12. tarjan 模板二、数学1. 剩余定理2. N!中质因子P的个数3.拓展欧几里得4.三角形的各中心到顶点的距离和5.三角形外接圆半径周长6.归并排序求逆序数7. 求N!的位数8.欧拉函数9. Miller-Rabin,大整数分解,求欧拉函数10. 第一类斯特林数11.计算表达式12.约瑟夫问题13.高斯消元法14. Baby-step,giant-step n是素数.n任意15. a^b%c=a ^(b%eular(c)+eular(c)) % c16.判断第二类斯特林数的奇偶性17.求组合数C(n,r)18.进制转换19.Ronberg算法计算积分20.行列式计算21. 返回x 的二进制表示中从低到高的第i位22.高精度运算 +-*/23.超级素数筛选三、数据结构1.树状数组2.线段树求区间的最大、小值3.线段树求区间和4.单调队列5.KMP模板6. 划分树,求区间第k小数7.最大堆,最小堆模板8. RMQ模板求区间最大、最小值9.快速排序,归并排序求逆序数.10.拓展KMP四、计算几何1.凸包面积2.Pick公式求三角形内部有多少点3.多边形边上内部各多少点以及面积pick4.平面最远点对5.判断矩形是否在矩形内6.判断点是否在多边形内7.判断4个点(三维)是否共面8.凸包周长9.等周定理变形一直两端点和周长求最大面积10.平面最近点对11.单位圆最多覆盖多少点(包括边上)12.多边形费马点求点到多边形各个点的最短距离13.矩形并周长14.zoj 2500 求两球体积并一、图论1.最大团#include<iostream>#include<algorithm>using namespace std;int n,m;int cn;//当前顶点数int best;//当前最大顶点数int vis[50];//当前解int bestn[50];//最优解int map[50][50];//临界表void dfs(int i){if(i>n){for(int j=1;j<=n;j++) bestn[j]=vis[j];best=cn;return ;}int ok=1;for(int j=1;j<i;j++){if(vis[j]==1&&map[i][j]==0){ok=0;break;}}if(ok){//进入左子树vis[i]=1;cn++;dfs(i+1);cn--;}if(cn+n-i>best){//进入右子树vis[i]=0;dfs(i+1);}}int main(){while(scanf("%d%d",&n,&m)==2){memset(vis,0,sizeof(vis));memset(map,0,sizeof(map));while(m--){int p,q;scanf("%d%d",&p,&q);map[p][q]=map[q][p]=1;//无向图}cn=0;best=0;dfs(1);printf("%d\n",best);}return 0;}2.拓扑排序#include<iostream>#include<cstring>using namespace std;int map[105][105],in[105],vis[105],ans[105],n;int flag;void dfs(int step){if(flag) return ;if(step==n+1) {flag=1; printf("%d",ans[1]);for(int i=2;i<=n;i++) printf(" %d",ans[i]);printf("\n");return ;}for(int i=1;i<=n;i++){if(vis[i]==0&&in[i]==0){vis[i]=1;for(int j=1;j<=n;j++){if(map[i][j]>0){map[i][j]=-map[i][j];in[j]--;}}ans[step]=i;dfs(step+1);vis[i]=0;for(int j=1;j<=n;j++){if(map[i][j]<0){map[i][j]=-map[i][j];in[j]++;}}}}}int main(){while(scanf("%d",&n)==1){flag=0;memset(map,0,sizeof(map));memset(vis,0,sizeof(vis));memset(in,0,sizeof(in));for(int i=1;i<=n;i++){int t;while(scanf("%d",&t),t){map[i][t]=1;in[t]++;}}dfs(1);}return 0;}3.最短路和次短路#include<iostream>#include<cstdio>#include<vector>#include<cstring>using namespace std;class Node{public:int e,w;//表示终点和边权};const int inf=(1<<25);int main(){int ci;cin>>ci;while(ci--){vector<Node> G[1005];//用邻接表存边int n,m;cin>>n>>m;for(int i=1;i<=m;i++){Node q;int u;cin>>u>>q.e>>q.w;G[u].push_back(q);}int s,f;//起点和终点cin>>s>>f;//dijkstra 求最短路和次短路int flag[1005][2];int dis[1005][2],cnt[1005][2];//0表示最短路,1表示次短路memset(flag,0,sizeof(flag));for(int i=1;i<=n;i++) dis[i][0]=dis[i][1]=inf;dis[s][0]=0;cnt[s][0]=1;//初始化for(int c=0;c<2*n;c++) //找最短路和次短路,故要进行2*n次循环也可以改成while(1){int temp=inf,u=-1,k;//找s-S'集合中的最短路径,u记录点的序号,k记录是最短路或者是次短路for(int j=1;j<=n;j++){if(flag[j][0]==0&&temp>dis[j][0]) temp=dis[j][0],u=j,k=0;else if(flag[j][1]==0&&temp>dis[j][1]) temp=dis[j][1],u=j,k=1;}if(temp==inf) break;//S'集合为空或者不联通,算法结束//更新路径flag[u][k]=1;for(int l=0;l<G[u].size();l++){int d=dis[u][k]+G[u][l].w,j=G[u][l].e;//important//4种情况if(d<dis[j][0]){dis[j][1]=dis[j][0];cnt[j][1]=cnt[j][0];dis[j][0]=d;cnt[j][0]=cnt[u][k];}else if(d==dis[j][0]){cnt[j][0]+=cnt[u][k];}else if(d<dis[j][1]){dis[j][1]=d;cnt[j][1]=cnt[u][k];}else if(d==dis[j][1]){cnt[j][1]+=cnt[u][k];}}}int num=cnt[f][0];//最短路int cc=cnt[f][1];//次短路}return 0;}4.SAP模板#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int inf=(1<<31)-1;const int point_num=300;int cap[point_num][point_num],dist[point_num],gap[point_num];//初始化见main里面int s0,t0,n;//源,汇和点数int find_path(int p,int limit=0x3f3f3f3f){if(p==t0) return limit;for(int i=0;i<n;i++)if(dist[p]==dist[i]+1 && cap[p][i]>0){int t=find_path(i,min(cap[p][i],limit));if(t<0) return t;if(t>0){cap[p][i]-=t;cap[i][p]+=t;return t;}}int label=n;for(int i=0;i<n;i++) if(cap[p][i]>0) label=min(label,dist[i]+1);if(--gap[dist[p]]==0 || dist[s0]>=n ) return -1;++gap[dist[p]=label];return 0;}int sap(){//初始化s,ts0=0,t0=n-1;int t=0,maxflow=0;gap[0]=n;while((t=find_path(s0))>=0) maxflow+=t;return maxflow;}int main(){int ci;while(cin>>ci>>n){//初始化memset(cap,0,sizeof(cap));memset(dist,0,sizeof(dist));memset(gap,0,sizeof(gap));//初始化capwhile(ci--){int x,y,c;cin>>x>>y>>c;x--;y--;cap[x][y]+=c;//因题而异}int ans=sap();cout<<ans<<endl;}return 0;}5.已知各点度,问能否组成一个简单图#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int inf=(1<<30);int d[1100];bool cmp(int x,int y){return x>y;}int main(){int ci;scanf("%d",&ci);while(ci--){int n,flag=1,cnt=0;scanf("%d",&n); for(int i=0;i<n;i++){scanf("%d",&d[i]);if(d[i]>n-1||d[i]<=0) flag=0; cnt+=d[i];}if(flag==0||cnt%2){printf("no\n");continue;}sort(d,d+n,cmp);for(int l=n;l>0;l--){for(int i=1;i<l&&d[0];i++){d[0]--,d[i]--;if(d[i]<0){flag=0;break;}}if(d[0]) flag=0;if(flag==0) break;d[0]=-inf;sort(d,d+l,cmp);}if(flag) printf("yes\n");else printf("no\n");}return 0;}6.KRUSKAL#include<iostream>#include<algorithm>using namespace std;int u[15005],v[15005],w[15005],fath[15005],r[15005];int ans1[15005],ans2[15005];bool cmp(int i,int j){return w[i]<w[j];}int find(int x){return fath[x]==x?x:fath[x]=find(fath[x]);}int main(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++) fath[i]=i;for(int i=1;i<=m;i++) r[i]=i;for(int i=1;i<=m;i++){cin>>u[i]>>v[i]>>w[i];}sort(r+1,r+m+1,cmp);int maxn=0,ans=0,k=0;for(int i=1;i<=m;i++){int e=r[i];int x=find(u[e]),y=find(v[e]);if(x!=y){ans+=w[e];fath[x]=y;if(w[e]>maxn) maxn=w[e];ans1[k]=u[e];ans2[k++]=v[e];}}return 0;}7.prime求最小生成树语法:prim(Graph G,int vcount,int father[]);参数:G:图,用邻接矩阵表示vcount:表示图的顶点个数father[]:用来记录每个节点的父节点返回值:null注意:常数max_vertexes 为图最大节点数常数infinity为无穷大源程序:#define infinity 1000000#define max_vertexes 5typedef int Graph[max_vertexes][max_vertexes];void prim(Graph G,int vcount,int father[]){int i,j,k;intlowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes]; for (i=0;i<vcount;i++){lowcost[i]=G[0][i];closeset[i]=0;used[i]=0;father[i]=-1;}used[0]=1;for (i=1;i<vcount;i++){j=0;while (used[j]) j++;for (k=0;k<vcount;k++)if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;father[j]=closeset[j];used[j]=1;for (k=0;k<vcount;k++)if (!used[k]&&(G[j][k]<lowcost[k])){ lowcost[k]=G[j][k];closeset[k]=j; }}}8.Dijkstra语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]); 参数:G:图,用邻接矩阵表示n:图的顶点个数s:开始节点t:目标节点path[]:用于返回由开始节点到目标节点的路径返回值:最短路径长度注意:输入的图的权必须非负顶点标号从0 开始用如下方法打印路径:i=t;while (i!=s){printf("%d<--",i+1);i=path[i];}printf("%d\n",s+1);源程序:int Dijkstra(Graph G,int n,int s,int t, int path[]){int i,j,w,minc,d[max_vertexes],mark[max_vertexes];for (i=0;i<n;i++) mark[i]=0;for (i=0;i<n;i++){ d[i]=G[s][i];path[i]=s; }mark[s]=1;path[s]=0;d[s]=0;for (i=1;i<n;i++){minc=infinity;w=0;for (j=0;j<n;j++)if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}mark[w]=1;for (j=0;j<n;j++)if((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j])){ d[j]=d[w]+G[w][j];path[j]=w; }}return d[t];}9.Bellman-ford语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);参数:G:图,用邻接矩阵表示n:图的顶点个数s:开始节点t:目标节点path[]:用于返回由开始节点到目标节点的路径success:函数是否执行成功返回值:最短路径长度注意:输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0顶点标号从0 开始用如下方法打印路径:i=t;while (i!=s){printf("%d<--",i+1);i=path[i];}printf("%d\n",s+1);源程序:int Bellman_ford(Graph G,int n,int s,int t,int path[],int success){int i,j,k,d[max_vertexes];for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}d[s]=0;for (k=1;k<n;k++)for (i=0;i<n;i++)for (j=0;j<n;j++)if (d[j]>d[i]+G[i][j]){d[j]=d[i]+G[i][j];path[j]=i;}success=0;for (i=0;i<n;i++)for (j=0;j<n;j++)if (d[j]>d[i]+G[i][j]) return 0;success=1;return d[t];}10. SPFA#include<iostream>#include<cstdio>#include<cstring>#include<vector>using namespace std;const __int64 maxn=1001000;const __int64 inf=1000100000;struct edge//邻接表{__int64 t,w;//s->t=w;__int64 next;//数组模拟指针};__int64 p[maxn],pf[maxn];//邻接表头节点edge G[maxn],Gf[maxn];//邻接表__int64 V,E;//点数[1-n] 边数__int64 dis[maxn];__int64 que[maxn],fro,rear;//模拟队列__int64 vis[maxn];__int64 inque[maxn];//入队次数bool spfa(__int64 s0){fro=rear=0;for(__int64 i=1;i<=V;i++) dis[i]=inf;dis[s0]=0;memset(vis,0,sizeof(vis));memset(inque,0,sizeof(inque));que[rear++]=s0;vis[s0]=1;inque[s0]++;while(fro!=rear){__int64 u=que[fro];fro++;if(fro==maxn) fro=0;vis[u]=0;for(__int64 i=p[u];i!=-1;i=G[i].next){__int64 s=u,t=G[i].t,w=G[i].w;if(dis[t]>dis[s]+w){dis[t]=dis[s]+w;if(vis[t]==0){que[rear++]=t,vis[t]=1;inque[t]++;if(inque[t]>V) return false;if(rear==maxn) rear=0;}}}}return true;}int main(){__int64 ci;scanf("%I64d",&ci);while(ci--){scanf("%I64d%I64d",&V,&E);memset(p,-1,sizeof(p));memset(pf,-1,sizeof(pf)); for(__int64 i=0;i<E;i++){__int64 u,v,w;scanf("%I64d%I64d%I64d",&u,&v,&w);G[i].t=v;G[i].w=w;G[i].next=p[u];p[u]=i;Gf[i].t=u;Gf[i].w=w;Gf[i].next=pf[v];pf[v]=i;}__int64 ans=0;spfa(1);//求第一个点到其他点的最短距离和for(__int64 i=1;i<=V;i++) ans+=dis[i];//反方向再来一次spfa 求其他点到第一个点的最短距离和 for(__int64 i=1;i<=V;i++) p[i]=pf[i];for(__int64 i=0;i<E;i++) G[i]=Gf[i];spfa(1);for(__int64 i=1;i<=V;i++) ans+=dis[i];printf("%I64d\n",ans);}return 0;}11.Kosaraju模板#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;struct edge{int t,w;//u->t=w;int next;};int V,E;//点数(从1开始),边数int p[maxn],pf[maxn];//邻接表原图,逆图edge G[maxn],Gf[maxn];//邻接表原图,逆图int l,lf;void init(){memset(p,-1,sizeof(p));memset(pf,-1,sizeof(pf));l=lf=0;}void addedge(int u,int t,int w,int l){G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}void addedgef(int u,int t,int w,int lf){Gf[l].w=w;Gf[l].t=t;Gf[l].next=pf[u];pf[u]=l;}///Kosaraju算法,返回为强连通分量个数bool flag[maxn]; //访问标志数组int belg[maxn]; //存储强连通分量,其中belg[i]表示顶点i属于第belg[i]个强连通分量int numb[maxn]; //结束时间(出栈顺序)标记,其中numb[i]表示离开时间为i的顶点//用于第一次深搜,求得numb[1..n]的值void VisitOne(int cur, int &sig){flag[cur] = true;for (int i=p[cur];i!=-1;i=G[i].next){if (!flag[G[i].t]){VisitOne(G[i].t,sig);}}numb[++sig] = cur;}//用于第二次深搜,求得belg[1..n]的值void VisitTwo(int cur, int sig){flag[cur] = true;belg[cur] = sig;for (int i=pf[cur];i!=-1;i=Gf[i].next){if (!flag[Gf[i].t]){VisitTwo(Gf[i].t,sig);}}//Kosaraju算法,返回为强连通分量个数int Kosaraju_StronglyConnectedComponent(){int i, sig;//第一次深搜memset(flag,0,sizeof(flag));for ( sig=0,i=1; i<=V; ++i ){if ( false==flag[i] ){VisitOne(i,sig);}}//第二次深搜memset(flag,0,sizeof(flag));for ( sig=0,i=V; i>0; --i ){if ( false==flag[numb[i]] ){VisitTwo(numb[i],++sig);}}return sig;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int u=i,t,w=1;while(scanf("%d",&t)==1&&t){E++;addedge(u,t,w,l++);addedgef(t,u,w,lf++);}}int ans=Kosaraju_StronglyConnectedComponent(); printf("%d\n",ans);}return 0;12.tarjan模板//自己模板#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;int V,E;//点数(1) 边数struct edge//邻接表{int t,w;//u->t=w;int next;};int p[maxn];//表头节点edge G[maxn];int l;void init(){memset(p,-1,sizeof(p));l=0;}//添加边void addedge(int u,int t,int w,int l)//u->t=w;{G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}//tarjan算法求有向图强联通分量int dfn[maxn],lowc[maxn];//dfn[u]节点u搜索的次序编号,lowc[u]u或者u的子树能够追溯到的栈中的最早的节点int belg[maxn];//第i个节点属于belg[i]个强连通分量int stck[maxn],stop;//stck栈int instck[maxn];//第i个节点是否在栈中int scnt;//强联通分量int index;void dfs(int i){dfn[i]=lowc[i]=++index;instck[i]=1;//节点i入栈stck[++stop]=i;for(int j=p[i];j!=-1;j=G[j].next){int t=G[j].t;//更新lowc数组if(!dfn[t])//t没有遍历过{dfs(t);if(lowc[i]>lowc[t]) lowc[i]=lowc[t];}//t是i的祖先节点else if(instck[t]&&lowc[i]>dfn[t]) lowc[i]=dfn[t];}//是强连通分量的根节点if(dfn[i]==lowc[i]){scnt++;int t;do{t=stck[stop--];instck[t]=0;belg[t]=scnt;}while(t!=i);}}int tarjan(){stop=scnt=index=0;memset(dfn,0,sizeof(dfn));memset(instck,0,sizeof(instck));for(int i=1;i<=V;i++){if(!dfn[i]) dfs(i);}return scnt;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int x;while(scanf("%d",&x)==1&&x){E++;addedge(i,x,1,l++);}}int ans=tarjan();printf("%d\n",ans);}return 0;}//吉大模板邻接表版#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000;int V,E;//点数(1) 边数struct edge//邻接表{int t,w;//u->t=w;int next;};int p[maxn];//表头节点edge G[maxn];int l;void init(){memset(p,-1,sizeof(p));l=0;}//添加边void addedge(int u,int t,int w,int l)//u->t=w;{G[l].w=w;G[l].t=t;G[l].next=p[u];p[u]=l;}//tarjan算法求有向图强联通分量int dfn[maxn],lowc[maxn];//dfn[u]节点u搜索的次序编号,lowc[u]u或者u的子树能够追溯到的栈中的最早的节点int stck[maxn],stop;//stck栈int pre[maxn];//int scnt;//强联通分量int cnt;//void dfs(int v)//1-V{int t,minc=lowc[v]=pre[v]=cnt++;stck[stop++]=v;for(int i=p[v];i!=-1;i=G[i].next){int pv=G[i].t;if(pre[pv]==-1) dfs(pv);if(lowc[pv]<minc) minc=lowc[pv]; }if(minc<lowc[v]){lowc[v]=minc;return ;}do{dfn[t=stck[--stop]]=scnt;lowc[t]=V;}while(t!=v);++scnt;}int tarjan(){stop=cnt=scnt=0;memset(pre,-1,sizeof(pre));for(int i=1;i<=V;i++){if(pre[i]==-1) dfs(i);}return scnt;}int main(){while(scanf("%d",&V)==1){init();for(int i=1;i<=V;i++){int x;while(scanf("%d",&x)==1&&x){E++;addedge(i,x,1,l++);}}int ans=tarjan();printf("%d\n",ans);}return 0;}二、数学1.剩余定理int mod(int c[],int b[],int n){int all_multy=1,sum=0;int i,j,x[5];for(i=0;i<n;i++)all_multy*=c[i];for(i=0;i<n;i++)x[i]=all_multy/c[i];for(i=0;i<n;i++){j=1;while((x[i]*j)%c[i]!=1)j++;x[i]*=j;}for(i=0;i<n;i++)sum+=(b[i]*x[i]);return sum%all_multy;}2.N!中质因子P的个数//对于任意质数p,n!中有(n/p+n/p^2+n/p^3+...)个质因子p。

ACM常用模板代码

ACM常用模板代码
for (i=0; i<l; i++)
{
k=s[i]*m+add;
if (k>=10)
{
s[i]=k%10;
add=k/10;
flag=1;
}
else
{
s[i]=k;
flag=0;
add=0;
}
}
if (flag)
{
l=i+1;
s[i]=add;
}
else l=i;
for (i=0; i<l; i++)
{
p=pr[i-1]*pr[1];
q=pi[i-1]*pi[1];
s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
pr[i]=p-q;
pi[i]=s-p-q;
}
for (it=0; it<=n-2; it=it+2)
{
vr=fr[it];
vi=fi[it];
fr[it]=vr+fr[it+1];
s2[i-j]=c;
}
s2[i+1]='\0';
}
7.最大公约数、最小公倍数
语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)
参数:
a:
int a,求最大公约数或最小公倍数
b:
int b,求最大公约数或最小公倍数
返回值:
返回最大公约数(hcf)或最小公倍数(lcd)
k=k+1;
sum=sum/10;
}
for (i=blen-2;i>=0;i--)

ACM模板

ACM模板

ACM模板---liang一.高精度计算: ------------------------------------------------------------ 31.高精度加法:----------------------------------------------------------- 31)C++ string类实现:----------------------------------------------- 3 2)字符数组char实现:----------------------------------------------- 32.高精度减法:----------------------------------------------------------- 41)C++ string类实现:------------------------------------------------ 4 2)字符数组char实现:------------------------------------------------ 53.高精度乘法------------------------------------------------------------- 51)字符数组char实现:------------------------------------------------ 5 2)C++ string类实现:------------------------------------------------ 64.高精度阶乘(压缩五位)------------------------------------------------- 65.高精度小数加法--------------------------------------------------------- 7 二.计算几何: -------------------------------------------------------------- 81.线段相交:------------------------------------------------------------- 82.点关于直线的对称点:点:(a,b),直线:Ax+By+C=0------------------------- 93.求凸包 ---------------------------------------------------------------- 94.多边形面积------------------------------------------------------------ 115.皮克定理:------------------------------------------------------------ 116.三角形: ------------------------------------------------------------- 121)点和三角形的关系------------------------------------------------- 12 2)三角形各种面积算法:--------------------------------------------- 137.两圆相交面积---------------------------------------------------------- 14 三.搜索: ------------------------------------------------------------------ 151.DFS(深度优先、回溯) -------------------------------------------------- 152.BFS(广度优先) -------------------------------------------------------- 16 四.数论: ----------------------------------------------------------------- 171.最大公约数,最小公倍数:---------------------------------------------- 172.欧几里德扩展:-------------------------------------------------------- 173.大数除法求余、快速幂取余:-------------------------------------------- 174.同余: --------------------------------------------------------------- 195.筛素数 --------------------------------------------------------------- 19 五.图论 ------------------------------------------------------------------- 201.并查集: ------------------------------------------------------------- 202.最小生成树:---------------------------------------------------------- 201) Prim算法------------------------------------------------------- 21 2)克鲁斯卡尔算法--------------------------------------------------- 223.最短路径: ------------------------------------------------------------ 231)最短路径dijkstra算法-------------------------------------------- 23 1)Floyd算法(最短路径)------------------------------------------- 284.最大匹配 ------------------------------------------------------------- 295.最大流 --------------------------------------------------------------- 31 六.数据结构 --------------------------------------------------------------- 331.RMQ ------------------------------------------------------------------ 332.树状数组 ------------------------------------------------------------- 351)一维树状数组------------------------------------------------------ 352)二维树状数组------------------------------------------------------ 37 七.各种处理函数 ----------------------------------------------------------- 381.字符串 --------------------------------------------------------------- 381)字符串分解函数strtok-------------------------------------------- 38 八.动态规划 --------------------------------------------------------------- 391.最长公共子序列-------------------------------------------------------- 392.单调递增(递减)最长子序列-------------------------------------------- 403.整数规划:------------------------------------------------------------ 42一.高精度计算:1.高精度加法:1)C++ string类实现:#include<string>void sum(string &a,string b) // a=a+b{ int i,j,k,c,s;while (a.length()>b.length()) b='0'+b;// a,b处理成一样长 while (b.length()>a.length()) a='0'+a;c=0;for (i=a.length()-1; i>=0; i--){ s=a[i]-48+b[i]-48+c;if ( s>9 ) { s=s%10; c=1;} else c=0;a[i]=48+s;}if ( c>0 ) a='1'+a;}2)字符数组char实现:#include<string.h>void add(char a[],char b[])//a=a+b{int i,j,k,sum=0;k=strlen(a)>strlen(b)?strlen(a):strlen(b);a[k+1]=0;for(i=strlen(a)-1,j=strlen(b)-1;i>=0||j>=0;i--,j--,k--){ if(i>=0) sum+=a[i]-'0'; if(j>=0) sum+=b[j]-'0';a[k]=sum%10+'0'; sum/=10;}if(sum) a[0]=sum+'0';else strcpy(a,&a[1]);}2.高精度减法:1)C++ string类实现:#include<string>void f(string &a,string b){int i,j,sum=0;for(i=a.length()-1,j=b.length()-1;i>=0||j>=0;i--,j--){sum+=a[i]-'0'; if(j>=0) sum-=b[j]-'0';if(sum<0) {a[i]=sum+10+'0';sum=-1;}else {a[i]=sum+'0';sum=0;}}if(a[0]=='0') a=&a[1];for(i=0;a[i]=='0'&&i<a.length();i++) ;if(i==a.length()) a="0";}2)字符数组char实现:#include <string.h>void jian(char a[],char b[])//a-=b{int i,j,sum=0;for(i=strlen(a)-1,j=strlen(b)-1;i>=0||j>=0;i--,j--){sum+=a[i]-'0'; if(j>=0) sum-=b[j]-'0';if(sum<0) {a[i]=sum+10+'0';sum=-1;}else {a[i]=sum+'0';sum=0;}}if(a[0]=='0') strcpy(a,&a[1]);for(i=0;a[i]=='0';i++) ;if(i==strlen(a)) strcpy(a,"0");}3.高精度乘法1)字符数组char实现:#include <string.h>void chen(char a[],char b[])//a=a*b{ int i,j,k,l,sum,c[410]={0};l=strlen(a)+strlen(b);for(i=strlen(b)-1;i>=0;i--)for(j=strlen(a)-1,k=i+j+1;j>=0;j--,k--){ sum=(b[i]-'0')*(a[j]-'0')+c[k];c[k]=sum%10;c[k-1]+=sum/10;}for(i=c[0]?0:1,j=0;i<l;i++)a[j++]=(c[i]+'0'); a[j]=0;}2)C++ string类实现:#include<string>void chenn(string &a,string b)//a=a*b{ int i,j,k,l,sum,c[410]={0};l=a.length()+b.length();for(i=b.length()-1;i>=0;i--)for(j=a.length()-1,k=i+j+1;j>=0;j--,k--){ sum=(b[i]-'0')*(a[j]-'0')+c[k];c[k]=sum%10;c[k-1]+=sum/10;}i=c[0]?0:1;while(a.length()<l-i) a=a+'0';for(j=0;i<l;i++)a[j++]=(c[i]+'0');}4.高精度阶乘(压缩五位)#include<iostream>#include<iomanip>using namespace std;int a[10000];int main(void){int i,n,w,up,j;while(cin>>n){for(w=a[0]=i=1;i<=n;i++){ for(j=0,up=0;j<w;j++){a[j]=i*a[j]+up;up=a[j]/100000;a[j]%=100000;}if(up) a[w++]=up;}cout<<a[w-1];for(i=w-2;i>=0;i--)cout<<setfill('0')<<setw(5)<<a[i]; cout<<endl;}}5.高精度小数加法#include<cstring>#include<algorithm>void quw0(char a[]) //去除尾部多余的零 eg: 3.5+3.5=7.0变成 7 { int i;for(i=0;i<strlen(a);i++) //判断有没有小数点if(a[i]=='.') break;if(i!=strlen(a)){i=strlen(a)-1;while(a[i]=='0') {a[i]=0;;i--;}if(a[i]=='.') a[i]=0;;}}void add(char *a,char *b)//a=a+b{int i=0,j=0,la=strlen(a),lb=strlen(b),sum=0;while((a[i]-'.')&&i<la) i++;while((b[j]-'.')&&j<lb) j++;if(i==la) {a[i]='.';la++;};if(j==lb) {b[j]='.';lb++;};while(la-i>lb-j) {b[lb]='0';lb++;}while(lb-j>la-i) {a[la]='0';la++;}if(la<lb) { swap(a,b); swap(la,lb); }a[la+1]=0;b[lb]=0;for(i=la-1,j=lb-1;i>=0;i--,j--){ if(a[i]=='.') {a[i+1]='.';continue;}sum+=a[i]-'0'; if(j>=0) sum+=b[j]-'0';a[i+1]=sum%10+'0'; sum/=10;}if(sum) a[0]=sum+'0';else strcpy(a,&a[1]);quw0(a);//根据题目需要是否保留尾0}二.计算几何:1.线段相交:int xj(point x1,point x2,point x3,point x4)//相交为1,不交为0{if(min(x1.x,x2.x)>max(x3.x,x4.x)||min(x1.y,x2.y)>max(x3.y,x4.y)||min(x3.x,x4.x)>max(x1.x,x2.x)||min(x3.y,x4.y)>max(x1.y,x2.y) )return 0;//不交:矩形排斥实验,最小的>最大的肯定不交int a,b,c,d;a=(x1.x-x2.x)*(x3.y-x1.y)-(x1.y-x2.y)*(x3.x-x1.x);//跨立实验 b=(x1.x-x2.x)*(x4.y-x1.y)-(x1.y-x2.y)*(x4.x-x1.x);c=(x3.x-x4.x)*(x1.y-x3.y)-(x3.y-x4.y)*(x1.x-x3.x);d=(x3.x-x4.x)*(x2.y-x3.y)-(x3.y-x4.y)*(x2.x-x3.x);return a*b<=0&&c*d<=0;}2.点关于直线的对称点:点:(a,b),直线:Ax+By+C=0#include <stdio.h>int main(){int n;float a,b,A,B,C,a1,b1;scanf("%d\n",&n);while(n--){ scanf("%f %f %f %f %f",&a,&b,&A,&B,&C);int a1=int (a-2*A*(A*a+B*b+C)/(A*A+B*B));int b1=int (b-2*B*(A*a+B*b+C)/(A*A+B*B));printf("%d %d\n",a1,b1);}}3.求凸包//根据题目改动数据类型,数组大小,排序方式#include <algorithm>#define eps 1e-8struct point{int x,y;};point pnt[100003],res[100005];bool operator<( point A,point B )//按y排也可,具体看题目要求{ return A.x < B.x || (A.x == B.x && A.y < B.y); }double mult(point p0,point p1,point p2){ r eturn (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); }//数组下标从0开始,n是点的个数,选中的点在保存在res数组中,个数是topint graham(point pnt[], int n, point res[])//选中的点在保存在res数组中,个数是top{ int i, len, k = 0, top = 1;sort(pnt, pnt + n); //用cmp可能超时,原因未知if (n == 0) return 0; res[0] = pnt[0];if (n == 1) return 1; res[1] = pnt[1];if (n == 2) return 2; res[2] = pnt[2];for (i = 2; i < n; i++){ while (top && mult(pnt[i], res[top], res[top-1])<=eps) top--;res[++top] = pnt[i];}len = top; res[++top] = pnt[n - 2];for (i = n - 3; i >= 0; i--){ while (top!=len && mult(pnt[i], res[top], res[top-1])<=eps) top--;res[++top] = pnt[i];}return top; // 返回凸包中点的个数}4.多边形面积//点必须是顺时针给出或逆时针给出才可用此法//使用时注意数据类型,和数据大小struct point{int x,y;}a[105];int duo(point a[],int n) //点在数组 a[]中,个数是n{ int i,s=0;for(i=1;i<=n;i++)s+=(a[i-1].x*a[i%n].y-a[i-1].y*a[i%n].x);if(s<0) s=-s;return s;// if(s%2) cout<<s/2<<".5"<<endl; 若为longl long 类型,不要用double// else cout<<s/2<<".0"<<endl;}5.皮克定理://S=a+b÷2-1//(其中a表示多边形内部的点数,b表示多边形边界上的点数,S表示多边形的面积)#include<cmath>struct point{int x,y;};int gcd(int m,int n){if(n==0) return m;return gcd(n,m%n);}int bian(point a[],int n)//算出点A和点B组成的线段上的点{ int s=0,i;for(i=1;i<=n;i++)s+=gcd(abs(a[i-1].x-a[i%n].x),abs(a[i-1].y-a[i%n].y));return s;}int duo(point a[],int n)//求n边形的面积,注意ans未除2;{int i,s=0;for(i=1;i<=n;i++)s+=(a[i-1].x*a[i%n].y-a[i-1].y*a[i%n].x);if(s<0) s=-s;return s;}6.三角形:1)点和三角形的关系//注意数据类型#include <cmath>struct point{int x,y;};bool operator ==(point A,point B){return A.x==B.x&&A.y==B.y;} int area(point A,point B,point C)//三角形面积,未除2{int s=abs((B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x));return s;}int pan3(point a[],point p) //若点在三角形内(不含边界),返回1;{int sa,sb,sc,s;s=area(a[0],a[1],a[2]);sa=area(a[0],a[1],p);sb=area(a[0],a[2],p);sc=area(a[1],a[2],p);if(sa&&sb&&sc&&s==sa+sb+sc) return 1;if((!sa||!sb||!sc)&&s==sa+sb+sc){if(p==a[0]||p==a[1]||p==a[2]) return 4;//若点在三角形顶点上,返回4。

acm常用模板

acm常用模板

ACM Fighting!ACM Fighting! (2)1.计算几何 (5)1.1 注意 (5)1.2几何公式 (6)1.3 多边形 (8)1.4多边形切割 (11)1.5 浮点函数 (12)1.6 面积 (18)1.7球面 (18)1.8三角形 (19)1.9三维几何 (22)1.10 凸包 (30)1.11 网格 (32)1.12 圆 (33)1.13 矢量运算求几何模板 (35)1.14结构体表示几何图形 (47)1.15四城部分几何模板 (52)1.16 一些代码 (54)1.16.1 最小圆覆盖_zju1450 (54)1.16.2 直线旋转_两凸包的最短距离(poj3608) (58)1.16.3 扇形的重心 (62)1.16.4 根据经度纬度求球面距离 (62)1.16.5 多边形的重心 (64)1.16.6 存不存在一个平面把两堆点分开(poj3643) (66)1.16.7 pku_3335_判断多边形的核是否存在 (67)1.16.8 pku_2600_二分+圆的参数方程 (74)1.16.9 pku_1151_矩形相交的面积 (76)1.16.10 pku_1118_共线最多的点的个数 (78)1.16.11 pku2826_线段围成的区域可储水量 (80)1.16.12 Pick公式 (84)1.16.13 N点中三个点组成三角形面积最大 (86)1.16.14 直线关于圆的反射 (89)1.16.15 pku2002_3432_N个点最多组成多少个正方形(hao) (94)1.16.16 pku1981_单位圆覆盖最多点(poj1981)CircleandPoints (97)1.16.17 pku3668_GameofLine_N个点最多确定多少互不平行的直线(poj3668) (99)1.16.18 求凸多边形直径 (100)2.组合 (102)2.1 组合公式 (102)2.2 排列组合生成 (102)2.3 生成gray码 (104)2.4 置换(polya) (104)2.5 字典序全排列 (105)2.6 字典序组合 (105)2.7 一些原理及其例子 (106)3.数论 (108)3.1 阶乘最后非0位 (108)3.2 模线性方程组 (108)3.3 素数 (110)3.4 欧拉函数 (114)3.6高精度 (116)3.6.1平方根 (116)3.6.2 高精度乘幂 (117)3.7 高斯消元回代法 (122)3.8 数值计算 (124)3.8.1 定积分计算 (124)3.8.2 多项式求根(牛顿法) (125)3.8.3 周期性方程(追赶法) (127)4.排序 (128)4.1快速选择算法 (128)4.2归并排序+逆序数的求取 (128)5.字符串 (130)5.1 KMP应用 (130)5.2 后缀数组 (131)5.3 中缀表达式转后缀表达式 (134)5.4 Firefighters 表达式求值 (135)6.博弈 (139)6.1 博弈的AB剪枝 (139)6.2 博弈SG函数局势分割 (141)7.数据结构 (142)7.1 TRIE (142)7.2 线段树 (147)7.3 并查集 (151)7.4 树状数组 (152)7.5 点树 (154)7.6 STL (156)7.7 离散化 (157)8.图论 (158)8.0 2-SAT (158)8.2 寻找Euler回路 (163)8.3 拓扑排序 (163)8.4 差分约束系统 (164)8.5 笛卡尔树 (165)8.6 LCA和RMQ (167)8.7 割和桥 (171)8.8 最小生成树(kruskal) (172)8.9 最短路径 (173)8.10 最大网络流 (175)8.11 最小费用流 (180)8.12 最大团问题 (182)8.13 二分图匹配 (184)8.14 带权的最优二分图匹配 (184)9.搜索算法概略 (187)9.1 迭代深搜+IDA* (187)9.2 分之界限法(深搜) (189)9.3 A* 8数码问题( pascal ) (192)9.4 优先队列广搜 (194)10.应用 (197)10.1 Joseph问题 (197)10.3 布尔母函数 (198)10.4 第k元素 (199)10.5 幻方构造 (199)10.6 模式匹配(kmp) (201)10.7 逆序对数 (201)10.8 字符串最小表示 (202)10.9 最长公共单调子序列 (202)10.10 最长子序列 (204)10.11 最大子串匹配 (204)10.12 最大子段和 (205)10.13 最大子阵和 (206)11.其它 (207)11.1 大数(只能处理正数) (207)11.2 分数 (212)11.3 矩阵 (214)11.4 线性方程组 (216)11. 5 线性相关 (218)11.6 日期 (219)11.7 读入 (220)11.8 函数 (220)1.计算几何1.1 注意1. 注意舍入方式(0.5的舍入方向);防止输出-0.2. 几何题注意多测试不对称数据.3. 整数几何注意xmult和dmult是否会出界;符点几何注意eps的使用.4. 避免使用斜率;注意除数是否会为0.5. 公式一定要化简后再代入.6. 判断同一个2*PI域内两角度差应该是abs(a1-a2)<beta||abs(a1-a2)>pi+pi-beta;相等应该是abs(a1-a2)<eps||abs(a1-a2)>pi+pi-eps;7. 需要的话尽量使用atan2,注意:atan2(0,0)=0,atan2(1,0)=pi/2,atan2(-1,0)=-pi/2,atan2(0,1)=0,atan2(0,-1)=pi.8. cross product = |u|*|v|*sin(a)dot product = |u|*|v|*cos(a)9. (P1-P0)x(P2-P0)结果的意义:正: <P0,P1>在<P0,P2>顺时针(0,pi)内负: <P0,P1>在<P0,P2>逆时针(0,pi)内0 : <P0,P1>,<P0,P2>共线,夹角为0或pi10. 误差限缺省使用1e-8!1.2几何公式三角形:1. 半周长P=(a+b+c)/22. 面积S=aHa/2=absin(C)/2=sqrt(P(P-a)(P-b)(P-c))3. 中线Ma=sqrt(2(b^2+c^2)-a^2)/2=sqrt(b^2+c^2+2bccos(A))/24. 角平分线Ta=sqrt(bc((b+c)^2-a^2))/(b+c)=2bccos(A/2)/(b+c)5. 高线Ha=bsin(C)=csin(B)=sqrt(b^2-((a^2+b^2-c^2)/(2a))^2)6. 内切圆半径r=S/P=asin(B/2)sin(C/2)/sin((B+C)/2)=4Rsin(A/2)sin(B/2)sin(C/2)=sqrt((P-a)(P-b)(P-c)/P)=Ptan(A/2)tan(B/2)tan(C/2)7. 外接圆半径R=abc/(4S)=a/(2sin(A))=b/(2sin(B))=c/(2sin(C))四边形:D1,D2为对角线,M对角线中点连线,A为对角线夹角1. a^2+b^2+c^2+d^2=D1^2+D2^2+4M^22. S=D1D2sin(A)/2(以下对圆的内接四边形)3. ac+bd=D1D24. S=sqrt((P-a)(P-b)(P-c)(P-d)),P为半周长正n边形:R为外接圆半径,r为内切圆半径1. 中心角A=2PI/n2. 内角C=(n-2)PI/n3. 边长a=2sqrt(R^2-r^2)=2Rsin(A/2)=2rtan(A/2)4. 面积S=nar/2=nr^2tan(A/2)=nR^2sin(A)/2=na^2/(4tan(A/2))圆:1. 弧长l=rA2. 弦长a=2sqrt(2hr-h^2)=2rsin(A/2)3. 弓形高h=r-sqrt(r^2-a^2/4)=r(1-cos(A/2))=atan(A/4)/24. 扇形面积S1=rl/2=r^2A/25. 弓形面积S2=(rl-a(r-h))/2=r^2(A-sin(A))/2棱柱:1. 体积V=Ah,A为底面积,h为高2. 侧面积S=lp,l为棱长,p为直截面周长3. 全面积T=S+2A棱锥:1. 体积V=Ah/3,A为底面积,h为高(以下对正棱锥)2. 侧面积S=lp/2,l为斜高,p为底面周长3. 全面积T=S+A棱台:1. 体积V=(A1+A2+sqrt(A1A2))h/3,A1.A2为上下底面积,h为高(以下为正棱台)2. 侧面积S=(p1+p2)l/2,p1.p2为上下底面周长,l为斜高3. 全面积T=S+A1+A2圆柱:1. 侧面积S=2PIrh2. 全面积T=2PIr(h+r)3. 体积V=PIr^2h圆锥:1. 母线l=sqrt(h^2+r^2)2. 侧面积S=PIrl3. 全面积T=PIr(l+r)4. 体积V=PIr^2h/3圆台:1. 母线l=sqrt(h^2+(r1-r2)^2)2. 侧面积S=PI(r1+r2)l3. 全面积T=PIr1(l+r1)+PIr2(l+r2)4. 体积V=PI(r1^2+r2^2+r1r2)h/3球:1. 全面积T=4PIr^22. 体积V=4PIr^3/3球台:1. 侧面积S=2PIrh2. 全面积T=PI(2rh+r1^2+r2^2)3. 体积V=PIh(3(r1^2+r2^2)+h^2)/6球扇形:1. 全面积T=PIr(2h+r0),h为球冠高,r0为球冠底面半径2. 体积V=2PIr^2h/31.3 多边形#include <stdlib.h>#include <math.h>#define MAXN 1000#define offset 10000#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))struct point{double x,y;};struct line{point a,b;};double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); }//判定凸多边形,顶点按顺时针或逆时针给出,允许相邻边共线int is_convex(int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[1]|s[2];}//判定凸多边形,顶点按顺时针或逆时针给出,不允许相邻边共线int is_convex_v2(int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],p[(i+2)%n],p[i]))]=0;return s[0]&&s[1]|s[2];}//判点在凸多边形内或多边形边上,顶点按顺时针或逆时针给出int inside_convex(point q,int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[1]|s[2];}//判点在凸多边形内,顶点按顺时针或逆时针给出,在多边形边上返回0int inside_convex_v2(point q,int n,point* p){int i,s[3]={1,1,1};for (i=0;i<n&&s[0]&&s[1]|s[2];i++)s[_sign(xmult(p[(i+1)%n],q,p[i]))]=0;return s[0]&&s[1]|s[2];}//判点在任意多边形内,顶点按顺时针或逆时针给出//on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限int inside_polygon(point q,int n,point* p,int on_edge=1){point q2;int i=0,count;while (i<n)for (count=i=0,q2.x=rand()+offset,q2.y=rand()+offset;i<n;i++)if(zero(xmult(q,p[i],p[(i+1)%n]))&&(p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps&&(p[i].y-q.y)*(p[(i+1)%n].y-q.y)<eps) return on_edge;else if (zero(xmult(q,q2,p[i])))break;else if (xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])<-eps) count++;return count&1;}inline int opposite_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;}inline int dot_online_in(point p,point l1,point l2){return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}//判线段在任意多边形内,顶点按顺时针或逆时针给出,与边界相交返回1int inside_polygon(point l1,point l2,int n,point* p){point t[MAXN],tt;int i,j,k=0;if (!inside_polygon(l1,n,p)||!inside_polygon(l2,n,p))return 0;for (i=0;i<n;i++)if (opposite_side(l1,l2,p[i],p[(i+1)%n])&&opposite_side(p[i],p[(i+1)%n],l1,l2))return 0;else if (dot_online_in(l1,p[i],p[(i+1)%n]))t[k++]=l1;else if (dot_online_in(l2,p[i],p[(i+1)%n]))t[k++]=l2;else if (dot_online_in(p[i],l1,l2))t[k++]=p[i];for (i=0;i<k;i++)for (j=i+1;j<k;j++){tt.x=(t[i].x+t[j].x)/2;tt.y=(t[i].y+t[j].y)/2;if (!inside_polygon(tt,n,p))return 0;}return 1;}point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}point barycenter(point a,point b,point c){line u,v;u.a.x=(a.x+b.x)/2;u.a.y=(a.y+b.y)/2;u.b=c;v.a.x=(a.x+c.x)/2;v.a.y=(a.y+c.y)/2;v.b=b;return intersection(u,v);}//多边形重心point barycenter(int n,point* p){point ret,t;double t1=0,t2;int i;ret.x=ret.y=0;for (i=1;i<n-1;i++)if (fabs(t2=xmult(p[0],p[i],p[i+1]))>eps){t=barycenter(p[0],p[i],p[i+1]);ret.x+=t.x*t2;ret.y+=t.y*t2;t1+=t2;}if (fabs(t1)>eps)ret.x/=t1,ret.y/=t1;return ret;}1.4多边形切割//多边形切割//可用于半平面交#define MAXN 100#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)struct point{double x,y;};double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}int same_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;}point intersection(point u1,point u2,point v1,point v2){ point ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;return ret;}//将多边形沿l1,l2确定的直线切割在side侧切割,保证l1,l2,side不共线void polygon_cut(int& n,point* p,point l1,point l2,point side){ point pp[100];int m=0,i;for (i=0;i<n;i++){if (same_side(p[i],side,l1,l2))pp[m++]=p[i];if (!same_side(p[i],p[(i+1)%n],l1,l2)&&!(zero(xmult(p[i],l1,l2))&&zero(xmult(p[(i+1)%n],l1,l2)))) pp[m++]=intersection(p[i],p[(i+1)%n],l1,l2);}for (n=i=0;i<m;i++)if (!i||!zero(pp[i].x-pp[i-1].x)||!zero(pp[i].y-pp[i-1].y))p[n++]=pp[i];if (zero(p[n-1].x-p[0].x)&&zero(p[n-1].y-p[0].y))n--;if (n<3)n=0;}1.5 浮点函数//浮点几何函数库#include <math.h>#define eps 1e-8#define zero(x) (((x)>0?(x):-(x))<eps)struct point{double x,y;};struct line{point a,b;};//计算cross product (P1-P0)x(P2-P0)double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}double xmult(double x1,double y1,double x2,double y2,double x0,double y0){return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);}//计算dot product (P1-P0).(P2-P0)double dmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);}double dmult(double x1,double y1,double x2,double y2,double x0,double y0){return (x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);}//两点距离double distance(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}double distance(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}//判三点共线int dots_inline(point p1,point p2,point p3){return zero(xmult(p1,p2,p3));}int dots_inline(double x1,double y1,double x2,double y2,double x3,double y3){return zero(xmult(x1,y1,x2,y2,x3,y3));}//判点是否在线段上,包括端点int dot_online_in(point p,line l){return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;}int dot_online_in(point p,point l1,point l2){return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}int dot_online_in(double x,double y,double x1,double y1,double x2,double y2){return zero(xmult(x,y,x1,y1,x2,y2))&&(x1-x)*(x2-x)<eps&&(y1-y)*(y2-y)<eps;}//判点是否在线段上,不包括端点int dot_online_ex(point p,line l){return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y)); }int dot_online_ex(point p,point l1,point l2){return dot_online_in(p,l1,l2)&&(!zero(p.x-l1.x)||!zero(p.y-l1.y))&&(!zero(p.x-l2.x)||!zero(p.y-l2.y)); }int dot_online_ex(double x,double y,double x1,double y1,double x2,double y2){return dot_online_in(x,y,x1,y1,x2,y2)&&(!zero(x-x1)||!zero(y-y1))&&(!zero(x-x2)||!zero(y-y2));}//判两点在线段同侧,点在线段上返回0int same_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;}int same_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;}//判两点在线段异侧,点在线段上返回0int opposite_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;}int opposite_side(point p1,point p2,point l1,point l2){return xmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;}//判两直线平行int parallel(line u,line v){return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));}int parallel(point u1,point u2,point v1,point v2){return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));}//判两直线垂直int perpendicular(line u,line v){return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));}int perpendicular(point u1,point u2,point v1,point v2){return zero((u1.x-u2.x)*(v1.x-v2.x)+(u1.y-u2.y)*(v1.y-v2.y));}//判两线段相交,包括端点和部分重合int intersect_in(line u,line v){if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);}int intersect_in(point u1,point u2,point v1,point v2){if (!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);returndot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2); }//判两线段相交,不包括端点和部分重合int intersect_ex(line u,line v){return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);}int intersect_ex(point u1,point u2,point v1,point v2){return opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);}//计算两直线交点,注意事先判断直线是否平行!//线段交点请另外判线段相交(同时还是要判断是否平行!)point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}point intersection(point u1,point u2,point v1,point v2){point ret=u1;double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));ret.x+=(u2.x-u1.x)*t;ret.y+=(u2.y-u1.y)*t;return ret;}//点到直线上的最近点point ptoline(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;return intersection(p,t,l.a,l.b);}point ptoline(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;return intersection(p,t,l1,l2);}//点到直线距离double disptoline(point p,line l){return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);}double disptoline(point p,point l1,point l2){return fabs(xmult(p,l1,l2))/distance(l1,l2);}double disptoline(double x,double y,double x1,double y1,double x2,double y2){ return fabs(xmult(x,y,x1,y1,x2,y2))/distance(x1,y1,x2,y2);}//点到线段上的最近点point ptoseg(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;if (xmult(l.a,t,p)*xmult(l.b,t,p)>eps)return distance(p,l.a)<distance(p,l.b)?l.a:l.b;return intersection(p,t,l.a,l.b);}point ptoseg(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;if (xmult(l1,t,p)*xmult(l2,t,p)>eps)return distance(p,l1)<distance(p,l2)?l1:l2;return intersection(p,t,l1,l2);}//点到线段距离double disptoseg(point p,line l){point t=p;t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;if (xmult(l.a,t,p)*xmult(l.b,t,p)>eps)return distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);}double disptoseg(point p,point l1,point l2){point t=p;t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;if (xmult(l1,t,p)*xmult(l2,t,p)>eps)return distance(p,l1)<distance(p,l2)?distance(p,l1):distance(p,l2);return fabs(xmult(p,l1,l2))/distance(l1,l2);}//矢量V以P为顶点逆时针旋转angle并放大scale倍point rotate(point v,point p,double angle,double scale){point ret=p;v.x-=p.x,v.y-=p.y;p.x=scale*cos(angle);p.y=scale*sin(angle);ret.x+=v.x*p.x-v.y*p.y;ret.y+=v.x*p.y+v.y*p.x;return ret;}//p点关于直线L的对称点ponit symmetricalPointofLine(point p, line L){point p2;double d;d = L.a * L.a + L.b * L.b;p2.x = (L.b * L.b * p.x - L.a * L.a * p.x -2 * L.a * L.b * p.y - 2 * L.a * L.c) / d;p2.y = (L.a * L.a * p.y - L.b * L.b * p.y -2 * L.a * L.b * p.x - 2 * L.b * L.c) / d;return p2;}//求两点的平分线line bisector(point& a, point& b) {line ab, ans; ab.set(a, b);double midx = (a.x + b.x)/2.0, midy = (a.y + b.y)/2.0;ans.a = -ab.b, ans.b = -ab.a, ans.c = -ab.b * midx + ab.a * midy;return ans;}// 已知入射线、镜面,求反射线。

ACM常用模板 最大团(n小于64)(faster)

ACM常用模板 最大团(n小于64)(faster)

int sizeClique(vector<vector<int> >& mat);
// solve maximum clique and return constitution
vector<int> consClique(vector<vector<int> >& mat);
};
// search routine
}
~clique() {
delete bits;
}
// search routine
bool search(int step, int size, long long more, long long con);
// solve maximum clique and return size
/**
* WishingBone's ACM/ICPC Routine Library
*
* maximum clique solver
*/
#include <vector>
using std::vector;
// clique solver calculates both size and consitution of maximum clique
if (search(step + 1, size + 1, next, cons | now)) return true;
}
}
long long next = more & ~now;
if (size + bits[next & MASK] + bits[(next >> 21) & MASK] + bits[next >> 42]

ACM模板--我的第一份ACM模板

ACM模板--我的第一份ACM模板

求逆序数int solve(int f,int l){int mid=(f+l)/2,j=0,h1=f,h2=mid+1;int sum=0;if(f==l) return 0;sum+=(solve(f,mid)+solve(mid+1,l));for(;h1<=mid&&h2<=l;){if(str[i][h1]<=str[i][h2]){tem[j++]=str[i][h1];h1++;}else {tem[j++]=str[i][h2];h2++;sum+=mid-h1+1;}}while(h1<=mid){tem[j++]=str[i][h1++];}while(h2<=l){tem[j++]=str[i][h2++];}memcpy(&str[i][f],tem,sizeof(char)*j);return sum;}经典宽搜visited[a.x][a.y]=0;while (s != e && s<=N*N && e<=N*N){c = queue[s];if (c.x == b.x && c.y == b.y) break;for (i=0;i<8;i++){c = queue[s];c.x += d[i][0];c.y += d[i][1];if (visited[c.x][c.y]==1 && c.x>=0 && c.x<l && c.y>=0 && c.y<l){visited[c.x][c.y]=0;c.step++;queue[e++]=c;}}s++;}深搜一道void DFS(int a,int b){int i,j;if(putk == k){sum++;return;}visited[b]=1;for(i=a+1;i<n;i++)for(j=0;j<n;j++)if(c[i][j]=='#' && visited[j]==0){putk++;DFS(i,j);putk--;}visited[b]=0;}滑雪DPint f(int a,int b){int tem=0;if(visited[a][b]==1) return arr[a][b];if(a-1>=0 && map[a-1][b]<map[a][b])if(tem<f(a-1,b)) tem=f(a-1,b);if(a+1<r && map[a+1][b]<map[a][b])if(tem<f(a+1,b)) tem=f(a+1,b);if(b-1>=0 && map[a][b-1]<map[a][b])if(tem<f(a,b-1)) tem=f(a,b-1);if(b+1<c && map[a][b+1]<map[a][b])if(tem<f(a,b+1)) tem=f(a,b+1); //此处切记不要把f写成arr!!visited[a][b]=1;arr[a][b]=tem+1;return arr[a][b];}最长上升子序列(二分)for(i=0;i<n;i++){left=1;right=len;while(left<=right){mid=(left+right)/2;if(b[mid]<a[i]) left=mid+1;else right=mid-1;}b[left]=a[i];f[i]=left;if(len<left) len=left;if(ans<left) ans=left;}最长上升子序列void DP(int x){int i,j=0,max=0;for(i=0;i<x;i++)if(a[i]<a[x]) h[j++]=f[i];for(i=0;i<j;i++)if(max<h[i]) max=h[i];f[x]=max+1;}01背包int main(){int i,ans,j,t;scanf("%d%d",&n,&m);for(i=0;i<n;i++)scanf("%d%d",&a[i].w,&a[i].d);for(i=0;i<=m;i++)f[0][i]=0;for(i=1,t=1;i<=n;i++,t=1-t)for(j=0;j<=m;j++){f[t][j]=f[1-t][j];if(j>=a[i-1].w && f[1-t][j-a[i-1].w]+a[i-1].d>f[t][j])f[t][j]=f[1-t][j-a[i-1].w]+a[i-1].d;}ans=f[1-t][m];printf("%d\n",ans);}最长公共子序列•若给定序列X={x1,x2,…,x m},则另一序列Z={z1,z2,…,z k},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,i k}使得对于所有j=1,2,…,k有:z j=x ij。

acm模板byliyang

acm模板byliyang
【正整数】 int getint(){ char c=getchar(); int t=0; while(c<'0'||c>'9'){ c=getchar(); } while(c>='0'&&c<='9'){ t=t*10+c-'0'; c=getchar(); } return t; }
【含负数】 int getint(){ int t=0,flag=1; char c=getchar(); while(c<'0'||c>'9'||c=='-'){ if(c=='-') flag=-1 ; c=getchar(); } while(c>='0'&&c<='9'){ t=t*10+c-'0'; c=getchar(); } return t*flag; }
【常用头文件】 #include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> #include <string> #include <string.h> #include <stdlib.h> #include <map> #include <queue> #include <stack> #include <vector> #include <limits.h> //INT_MAX 在此

ACM(五篇范例)

ACM(五篇范例)

ACM(五篇范例)第一篇:ACMDijkstra 模板/*************************************** * About:有向图的Dijkstra算法实现 * Author:Tanky Woo * Blog:t=0;if(flag == 0){printf(“Non”);}else{for(int i=min;i<=max;++i){if(mark[i]==1 && arr[i]==0)cnt++;}}if(cnt==1)printf(“Yesn”);elseprintf(“Non”);}} return 0;搜索算法模板BFS:1.#include2.#include3.#include4.#includeing namespace std;6.const int maxn=100;7.bool vst[maxn][maxn];// 访问标记8.int dir[4][2]={0,1,0,-1,1,0,-1,0};// 方向向量9.10.struct State // BFS 队列中的状态数据结构 11.{ 12.int x,y;// 坐标位置13.int Step_Counter;// 搜索步数统计器14.};15.16.State a[maxn];17.18.boolCheckState(State s)// 约束条件检验19.{ 20.if(!vst[s.x][s.y] &&...)// 满足条件 1: 21.return 1;22.else // 约束条件冲突 23.return 0;24.} 25.26.void bfs(State st)27.{ 28.queue q;// BFS 队列29.State now,next;// 定义 2 个状态,当前和下一个30.st.Step_Counter=0;// 计数器清零 31.q.push(st);// 入队32.vst[st.x][st.y]=1;// 访问标记33.while(!q.empty())34.{ 35.now=q.front();// 取队首元素进行扩展36.if(now==G)// 出现目标态,此时为Step_Counter 的最小值,可以退出即可37.{ 38.......// 做相关处理39.return;40.} 41.for(int i=0;i<4;i++)42.{ 43.next.x=now.x+dir[i][0];// 按照规则生成下一个状态44.next.y=now.y+dir[i][1];45.next.Step_Counter=now.Step_Coun ter+1;// 计数器加1 46.if(CheckState(next))// 如果状态满足约束条件则入队 47.{ 48.q.push(next);49.vst[next.x][next.y]=1;//访问标记 50.} 51.} 52.q.pop();// 队首元素出队53.} 54.return;55.} 56.57.int main()58.{ 59.......60.return 0;61.}代码:胜利大逃亡Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会.魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.Input 输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.然后是A块输入数据(先是第0块,然后是第1块,第2块......),每块输入数据有B行,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙.(如果对输入描述不清楚,可以参考Sample Input中的迷宫描述,它表示的就是上图中的迷宫) 特别注意:本题的测试数据非常大,请使用scanf输入,我不能保证使用cin能不超时.在本OJ上请使用Visual C++提交.Output 对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1.Sample Input 1 3 3 4 20 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 0 0 1 1 0 0 1 1 0Sample Output 11代码:#include #include #include #include #includeusing namespace std;int tx[] = {0,1,-1,0,0,0,0};int ty[] = {0,0,0,1,-1,0,0};int tz[] = {0,0,0,0,0,1,-1};int arr[55][55][55];int known[55][55][55];// 访问标记int a,b,c,d;struct state{int x,y,z;// 所在的坐标int step_count;//统计搜索步数。

ACM模板

ACM模板

1 快速幂求余模板2 中国剩余定理模板3: 欧拉函数4:log的用法5:已知半径以及圆上2点求圆心6打印素数表7 1到num中的所有数与m个质因子不互质的个数可以用来求a到b的数中与n互质的数的个数8 大数9求一个很大的数的质因子10单调递增或递减最长子序列复杂度O(n^2)11 最长公共子序列:输出s1 和s2 的最长公共子序列不一定连续如abcde aafe 则结果为ae12 日期处理类相关函数13 线性相关14 set+结构体15 快速输入法16 N点中三个点组成三角形面积最大17 并查集+ 字典树并查集t个树的的树节点的数目18 矩阵19 bitset 函数20 哈弗曼编码21 表达式计算&& 表达式判断22 最优流水作业调度23 卡特兰数24 二分匹配25 归并排序26 字典树27 二叉树的建立1 快速幂求余模板___________________________________经改进后代码如下:(输入a,k,m,求a^k%m)long f(long a,long k,long m){long b=1;while(k>=1){if(k%2==1) b=a*b%m;a=a*a%m;k=k/2;}return b;}2 中国剩余定理模板________________________________________/*如x=a1%m1 x=a2%m2 x=a3%m3 求x a[]存放a1 a2 。

w[]存放m1 m2.。

*/ #include <iostream>using namespace std;int Extended_Euclid(int a,int b,int &x,int &y) //扩展欧几里得算法{int d;if(b==0){x=1;y=0;return a;}d=Extended_Euclid(b,a%b,y,x);y-=a/b*x;return d;}int Chinese_Remainder(int a[],int w[],int len) //中国剩余定理a[]存放余数w[]存放两两互质的数{int i,d,x,y,m,n,ret;ret=0;n=1;for (i=0;i<len;i++)n*=w[i];for (i=0;i<len;i++){m=n/w[i];d=Extended_Euclid(w[i],m,x,y);ret=(ret+y*m*a[i])%n;}return (n+ret%n)%n;}int main(){int n,i;int w[15],b[15];while (scanf("%d",&n),n){for (i=0;i<n;i++){scanf("%d%d",&w[i],&b[i]);}printf("%d/n",Chinese_Remainder(b,w,n));}return 0;}3: 欧拉函数____________________________________________ __int64 euler(__int64 x)// 就是公式{__int64 i, res=x;for (i = 2; i <(__int64)sqrt(x * 1.0) + 1; i++)if(x%i==0){res = res /(__int64)i*(i - 1);while (x % i == 0) x /= i; // 保证i一定是素数}if (x > 1) res = res / (__int64)x*(x - 1);//这里小心别溢出了return res;}打表方法:#define maxn 40000-1int phi[40000];void get_PHI(){int i,j;for (i = 1; i <= maxn; i++) phi[i] = i;for (i = 2; i <= maxn; i += 2) phi[i] /= 2;for (i = 3; i <= maxn; i += 2) if(phi[i] == i){for (j = i; j <= maxn; j += i)phi[j] = phi[j] / i * (i - 1);}}4: log 的用法____________________________________________求lnx为log(x) 这些绝对正确求log 10 x是log10(x)没有专门的求任意底数对数的函数,不过可以用log(x)/log(y)表示log y xln是以e为底lg是以10为底exp(x)=数学中e^x所以exp(2)=e的平方log(x)=数学中ln(x)所以log(2)=ln25:已知半径以及圆上2点求圆心___________________________________const static double eps = 1e-6;struct Point{double x,y;};double distancess(Point a,Point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}Point look_center(Point a,Point b) //已知半径以及圆上2点(不是圆内)求圆心代码:a,b是圆上点{Point aa,bb,mid;aa.x = b.x-a.x;aa.y = b.y-a.y;mid.x = (a.x+b.x)/2.0;mid.y = (a.y+b.y)/2.0;double dist = distancess(a,mid);double c = sqrt(1.0-dist); //1.0是半径套用代码时要根据题意改变// if(fabs(aa.y)<eps)// {// bb.x = mid.x;// bb.y = mid.y+c; //这几句nop掉的话加上可以减少时间不加也能过不知道是干嘛的// }// else// {double ang = atan(-aa.x/aa.y);bb.x = mid.x + c*cos(ang);bb.y = mid.y + c*sin(ang);// }return bb;//用结构体变量bb存储圆心的坐标并返回}6打印素数表________________________________________#include<math.h>__int64 prime[100000],c;__int64 vis[1000000+10];void get_prime(){__int64 i,j,n=1000000,m;c=0;m=(__int64)sqrt(n+0.5);memset(vis,0,sizeof(vis));for(i=2;i<=m;i++)if(!vis[i]){for(j=i*i;j<=n;j+=i) vis[j]=1;}for(j=2;j<=n;j++) if(!vis[j])prime[c++]=j;}7 1到num中的所有数与m个质因子不互质的个数____________________可以用来求a到b的数中与n互质的数的个数#define LL long longLL prime[maxn];LL make_ans(LL num,int m)//1到num中的所有数与m个质因子不互质的个数注意是不互质哦{LL ans=0,tmp,i,j,flag;for(i=1;i<(LL)(1<<m);i++){ //用二进制来1,0来表示第几个素因子是否被用到,如m=3,三个因子是2,3,5,则i=3时二进制是011,表示第2、3个因子被用到tmp=1,flag=0;for(j=0;j<m;j++)if(i&((LL)(1<<j)))//判断第几个因子目前被用到flag++,tmp*=prime[j];if(flag&1)//容斥原理,奇加偶减ans+=num/tmp;elseans-=num/tmp;}return ans;}8/*我个人的大叔模板以及防止超时相乘模板_____________________ */#include<stdio.h>#include<string.h>char a[1000],b[1000];int daozhi(char str[],int d){char i,temp;for(i=0;i<d/2;i++){temp=str[i];str[i]=str[d-1-i];str[d-i-1]=temp;}return 0;}int main(){int i,j,d_a,d_b,ge,shi,ji,flag=0;int result[1000];char *p;for(i=0;i<1000;i++) result[i]=0;p=a;printf("请输入第一个数:\n");scanf("%s",p);p=b;printf("请输入第二个数:\n");scanf("%s",p);d_a=strlen(a);d_b=strlen(b);daozhi(a,d_a);daozhi(b,d_b);for(i=0;i<d_a;i++){for(j=0;j<d_b;j++){ji=(a[i]-48)*(b[j]-48);result[i+j]=result[i+j]+ji;}}for(i=0;i<1000;i++){if(result[i]>=10){result[i+1]=result[i+1]+result[i]/10;result[i]=result[i]%10;}}for(i=1000;i>=0;i--){if(result[i]!=0) {flag=i;break;}}for(i=flag;i>=0;i--)printf("%d",result[i]);}防止超时相乘模板/*网上复制思路:* 把9个1位数压缩成1个9位数* 相当于1个5W位数变成了1个6K位数* 复杂度变成了: 6000 * 6000 = 3600W* 杭电提交: 900+MS 低空掠过*/#include <algorithm>#include <iostream>#include <string.h>using namespace std;#define N 13000#define M 51000__int64 a[N],b[N],ans[N];char ca[M], cb[M];int StrToNum(char c[],__int64 num[]) //将字符串转成数字{int n=strlen(c),k=0;__int64 tp=0,p=1,d=1;for(int j=n-1;j>=0;j--){tp+=(__int64)(c[j]-'0')*d; //注意数字的顺序,合成一个数也是从低位到高位if(p>=9) //把9个1位数压成1个9位数,减少循环{num[k++] = tp;tp = 0;p = d = 1;}else{p++;d*=10;}}num[k++] = tp;return k;}int main(){int na,nb,n,t,d=0,i,j;const int width = 9;__int64 MOD =1000000000; //9位的模数while(scanf("%s%s", ca, cb)!=EOF){memset(a,0,sizeof(a));memset(b,0,sizeof(b));na=StrToNum(ca,a);nb=StrToNum(cb,b);memset(ans, 0, sizeof(ans));for(i=0;i<na;i++){for(j=0;j<nb;j++){ans[i+j]+=a[i]*b[j];}for(j=0;j<nb;j++){if(ans[i+j]>=MOD){ans[i+j+1]+=ans[i+j]/MOD;ans[i+j]%=MOD;}}}n=i+j+2;while(!ans[n]&&n>0) n--;if(n>=0) printf("%I64d",ans[n--]);while(n>=0) printf("%0*I64d",width,ans[n--]);//神马意识???不懂啊求大神解释printf("\n");}return 0;}大数相加减模板#include <iostream>#include<stdio.h>#include <string>#include<string.h>using namespace std;string add(const string& a,const string& b){string result; //用于记录计算结果int len_a = a.length() - 1;int len_b = b.length() - 1;int carry = 0; //进位for(;len_a>=0 && len_b>=0;len_a--,len_b--){int t = (a[len_a] - '0') + (b[len_b] - '0') + carry;carry = t/10;t %= 10;result += char(t+'0');}for(;len_a>=0;len_a--){int t = (a[len_a] - '0') + carry;carry = t/10;t %= 10;result += char(t+'0');}for(;len_b>=0;len_b--){int t = (b[len_b] - '0') + carry;carry = t/10;t %= 10;result += char(t+'0');}if(carry != 0){result += char(carry+'0');}//反转int len_r = result.length();for(int i = 0;i<len_r/2;i++){char temp = result[i];result[i] = result[len_r-i-1];result[len_r-i-1] = temp;}return result;}string sub(const string& a,const string& b){string result; //用于记录计算结果string big;string small;int i;int len_a = a.length();int len_b = b.length();int borrow = 0; //借位int sign = 1; //符号位if(len_a < len_b){sign = -1;big = b;small = a;}else if(len_a == len_b && pare(b)<0){sign = -1;big = b;small = a;}elsebig = a;small = b;}//big - smalllen_a = big.length() - 1;len_b = small.length() - 1;for(;len_a>=0 && len_b>=0;len_a--,len_b--) {int t = big[len_a] - small[len_b] - borrow;borrow = (t >= 0) ? 0 : 1;if(t < 0){t += 10;}result += char(t+'0');}for(;len_a>=0;len_a--){int t = big[len_a] - '0'- borrow;borrow = (t >= 0) ? 0 : 1;if(t < 0){t += 10;}result += char(t+'0');}int len_r = result.length();for(i = 0;i<len_r/2;i++){char temp = result[i];result[i] = result[len_r-i-1];result[len_r-i-1] = temp;}string r;if(sign == -1){r += '-';}for(i = 0;i<len_r;i++)if(result[i] != '0'){r += result.substr(i);break;}}return r;}string GetSubResult(const string& a,const string& b) {string result;string aa = a;string bb = b;if(a[0] != '-' && b[0] == '-')//a - -b = a+b{bb = b.substr(1);result = add(aa, bb);}else if(a[0] == '-' && b[0] != '-')//-a - b = -(a+b){aa = a.substr(1);result = '-' + add(aa, bb);}else if(a[0] == '-' && b[0] == '-')//-a - -b = b - a{aa = a.substr(1);bb = b.substr(1);result = sub(bb, aa);}else{result = sub(aa, bb);}return result;}int main(){string a,b,c;char aa[1000],bb[1000];int cas;while(scanf("%d",&cas)!=EOF){while(cas--){scanf("%s %s",aa,bb);a=aa;b=bb;c=GetSubResult(a, b);printf("%s\n",c.c_str());}}return 0;}大数相除模板#include <stdio.h>#include <stdlib.h>#include<string.h>#define MAXLEN 1000#define MAXLEN1 100#define MAXLEN2 100void divi(char *num1, char *num2, char *quo){int i, j, k, r, len1, len2;int i_num1[2+MAXLEN]={0}, i_num2[2+MAXLEN2]={0}, i_num[2+MAXLEN2]={0}, i_tnum[2+MAXLEN2]={0};char c_num[2+MAXLEN2], c_tnum[2+MAXLEN2], s[MAXLEN], *p;len1 = strlen(num1);len2 = strlen(num2);for (i=1; i<=len1; i++)i_num1[i] = num1[i-1] - '0';for (i=1; i<=len2; i++)i_num2[i] = num2[i-1] - '0';i = 0;if ( len1<len2 ){s[i++] = '0';s[i++] = '.';j = 0;while( j<len2-len1-1 ){s[i++] = '0';j++;}}for (r=0; r<=len2; r++){i_num[r] = i_num1[r];c_num[r] = i_num[r] + '0';}c_num[r] = '\0';j = 1+len2;while( i < MAXLEN ){for (k=1; k<=9; k++){for (r=0; r<1+len2; r++)i_tnum[r] = 0;for (r=len2; r>=0; r--){i_tnum[r] += i_num2[r] * k;if( i_tnum[r]>=10 && r>=1 ){i_tnum[r-1] += i_tnum[r] / 10;i_tnum[r] %= 10;}c_tnum[r] = i_tnum[r] + '0';}c_tnum[1+len2] = '\0';if( strcmp(c_tnum, c_num) > 0 ) break;if( j==2+len1 && len1>=len2 ) s[i++] = '.';s[i++] = k-1 + '0';for (r=len2; r>=0; r--){if( k<=9 ){i_num[r] += i_num2[r];if( i_num[r]>=10 && r>=1 ){i_num[r-1] += 1;i_num[r] -= 10;}}i_num[r] -= i_tnum[r];if( i_num[r]<0 && r>=1 ){i_num[r-1] -= 1;i_num[r] += 10;}}for (r=0; r<len2; r++){i_num[r] = i_num[r+1];c_num[r] = i_num[r] + '0';}i_num[r] = i_num1[j++];c_num[r] = i_num[r] + '0';c_num[r+1] = '\0';}for (r=0; s[r]=='0' && s[r+1]!='.'; ) r++;for (p=quo; r<i; p++,r++) *p = s[r];*p = '\0';}{char s1[50], s2[50], *ps;printf("Input two numbers: \n");gets(s1);gets(s2);if((ps=(char *)malloc(sizeof(MAXLEN+1)))==NULL){printf("malloc failed!\n");exit(0);}divi(s1, s2, ps);printf("%s\n", ps);free(ps);return 0;9 求一个很大的数的质因子cnt2=0;for(i=1;i*i<n;++i)//找出n的所有约数if(n%i==0){num[cnt2++]=i;num[cnt2++]=n/i;}if(i*i==n&&n%i==0) num[cnt2++]=i;10单调递增或递减最长子序列复杂度O(n^2)______________________ #include<stdio.h>#include<stdlib.h>int main(){int n,m,i,j,max;int a[20],dp[20];scanf("%d",&n);while(n--){scanf("%d",&m);for(i=0;i<=m-1;i++){scanf("%d",&a[i]);dp[i]=1; //dp[i]的最小值为1}for(i=m-2;i>=0;i--){for(j=i+1;j<=m-1;j++){if((a[j]<a[i])&&(dp[i]<dp[j]+1)) //最长递减子序列则a[j]<a[i],而最长递增子序列则a[j]>a[i]。

02_ACM大数问题

02_ACM大数问题

工大ACM团队
核心代码及解释
湖南工业大学
char s[SIZE]; int sum[SIZE]; while(gets(s),strcmp(s,"0")) { for(i=(j=strlen(s))-1;i>=0;--i) sum[j-1-i]+=(s[i]-'0'); } for(i=0;i<100;++i) { c=0; //处理进位,c表示进位 c+=sum[i]; sum[i]=c%10; c/=10; sum[i+1]+=c; }
工大ACM团队
大数运算-实例(除)
湖南工业大学
工大ACM团队
核心代码及解释
湖南工业大学
1. 2. 3. 4. 5. 6. 7. 8.
#include <stdio.h> #include <string.h> #define MAX_LEN 200 char szLine1[MAX_LEN + 10]; char szLine2[MAX_LEN + 10]; int an1[MAX_LEN + 10]; //被除数, an1[0]对应于个位 int an2[MAX_LEN + 10]; //除数, an2[0]对应于个位 int aResult[MAX_LEN + 10]; //存放商,aResult[0]对应于个 位 9. /* Substract 函数:长度为 nLen1 的大整数p1 减去长度为 nLen2 的大整数p2 10. 减的结果放在 p1 里,返回值代表结果的长度 11. 如不够减返回-1,正好减完返回 0
工大ACM团队
核心代码及解释

ACM比赛用的简单模板

ACM比赛用的简单模板

邵伯仲的模板凸包以斜率为基准的gr法#include<iostream>#include<algorithm>#include<vector>#include<math.h>using namespace std;typedef struct{int x,y;double k;}Node;Node *a;bool cmp(const Node &a,const Node &b)// 根据斜率和x进行排序{if (a.k==b.k) return a.x<b.x;return a.k<b.k;}bool mutiply(const Node &one,const Node &two,const Node &three)//差集{double p1x,p1y,p2x,p2y,result;p1x=two.x-one.x;p1y=two.y-one.y;p2x=three.x-one.x;p2y=three.y-one.y;result=p1x*p2y-p2x*p1y;if (result<=0) return true;return false;}double Area(const Node &one,const Node &two)//计算面积{double p1x,p1y,p2x,p2y,result;p1x=one.x-0;p1y=one.y-0;p2x=two.x-0;p2y=two.y-0;result=(p1x*p2y-p2x*p1y)/2;return result;}int main(){double sum;int last,count;vector <Node>s;Node one,two,three;int n,i,min,t;cin>>t;while(t--){cin>>n;a=new Node[n];sum=0;min=0;for(i=0;i<n;i++){cin>>a[i].x>>a[i].y;if (a[min].x>=a[i].x){if (a[min].x>a[i].x||a[min].y>a[i].y) min=i; }}if (n<3) {cout<<"0.0"<<endl;continue;}for(i=0;i<n;i++)//计算斜率{a[i].k=(double)(a[i].y-a[min].y)/(double)(a[i].x+1-a[min].x); }a[min].k=-2100000000;sort(a,a+n,cmp);//按斜率和x排序s.push_back(a[0]);//开始形成凸包s.push_back(a[1]);for(i=2;i<n;i++){last=s.size();two=s[last-1];one=s[last-2];while(mutiply(one,two,a[i])&&i<n&&s.size()>=2){s.pop_back();if(s.size()==1) break;last=s.size();two=s[last-1];one=s[last-2];}s.push_back(a[i]);}//形成了凸包last=s.size();//计算面积one=s[0];two=s[1];for(i=2;i<last;i++){sum+=Area(one,two);one=two;two=s[i];}sum+=Area(one,two);one=two;two=s[0];sum+=Area(one,two);printf("%.1f\n",sum);s.clear();}return 0;}筛法筛法处理素数#include<iostream>#include<cmath>using namespace std;#define MAX 1001bool la[MAX];void pick(){int i,j;memset(la,1,sizeof(la));la[1]=0;for(i=2;i<=sqrt(double(MAX-1));++i) {if (la[i]){for(j=i*i;j<=MAX-1;j+=i){la[j]=0;}}}}int main(){int i;pick();for(i=1;i<MAX;++i){if (la[i]) printf("%d ",i);}putchar('\n');return 0;}队列的stl实现#include <iostream>#include <queue>#include<vector>int main(){std::queue<int> a;std::priority_queue<int,std::vector<int>,std::less<int> > q;q.push(1);q.push(2);std::cout<<q.top()<<std::endl;return 0;}大数问题1 大数之整数加法#include<iostream>#include<string>using namespace std;string plus(const string &a,const string &b){string result,ttemp;int alen,blen,i,j;int add,temp;alen=a.size();blen=b.size();add=0;for(i=alen-1,j=blen-1;i>=0&&j>=0;i--,j--){temp=add+((int)a[i]-48)+((int)b[j]-48);add=temp/10;ttemp.push_back(temp%10+48);result.insert(0,ttemp);ttemp.clear();}while(i>=0){for(;i>=0;i--){temp=add+(a[i]-48);add=temp/10;ttemp.push_back(temp%10+48);result.insert(0,ttemp);ttemp.clear();}}while(j>=0){for(;j>=0;j--){temp=add+(b[j]-48);add=temp/10;ttemp.push_back(temp%10+48);result.insert(0,ttemp);ttemp.clear();}}if (add!=0){ttemp.push_back(add+48);result.insert(0,ttemp);ttemp.clear();}return result;}int main(){string a,b;a="";while(cin>>b&&b!="0"){a=plus(a,b);}cout<<a<<endl;return 0;}2计算大数小数乘法9位运算#include<iostream>#include<string>#include<cstring>using namespace std;void de0(string &s)//删除无效0{int slen,i;slen=s.length();if (s.find(".")!=-1){i=slen-1;while(s[i]=='0'||s[i]=='.'){if (s[i]=='.') {s.erase(i,1);break;}s.erase(i,1);i--;}}slen=s.length();while(s[0]=='0'&&s[1]!='.'&&slen!=1){s.erase(0,1);slen=s.length();}}int dex(string &multiplicand,string &multiplicator)//统计小数的位数并去掉小数点{int x1,x2,mcandlen,mtorlen,candloca,torloca;mcandlen=multiplicand.length();mtorlen=multiplicator.length();candloca=multiplicand.find(".");torloca=multiplicator.find(".");if (candloca!=-1) {x1=mcandlen-candloca-1;multiplicand.erase(candloca,1); }else x1=0;if (torloca!=-1) {x2=mtorlen-torloca-1;multiplicator.erase(torloca,1);}else x2=0;return x1+x2;}string multiplication( string &multiplicand,string &multiplicator) {int candlen,torlen,i,j,count,candg=0,torg=0,slen;__int64 *result,temp,*get_cand,*get_tor;string ch;string xresult;string str;int xlen;de0(multiplicand);de0(multiplicator);if (multiplicand=="0"||multiplicator=="0") return "0";xlen=dex(multiplicand,multiplicator);candlen=multiplicand.length();torlen=multiplicator.length();get_cand=new __int64[candlen/9+2];get_tor=new __int64[torlen/9+2];memset(get_cand,0,sizeof(get_cand));memset(get_tor,0,sizeof(get_tor));count=1;while (multiplicand.length()>=9){str=multiplicand.substr(multiplicand.length()-9);multiplicand.erase(multiplicand.length()-9);get_cand[count]=atoi(str.c_str());++count;}if (!multiplicand.empty()){str=multiplicand;multiplicand.clear();get_cand[count]=atoi(str.c_str());candg=count;}if (candg==0) candg=count-1;count=1;while (multiplicator.length()>=9){str=multiplicator.substr(multiplicator.length()-9);multiplicator.erase(multiplicator.length()-9);get_tor[count]=atoi(str.c_str());++count;}if (!multiplicator.empty()){str=multiplicator;multiplicator.clear();get_tor[count]=atoi(str.c_str());torg=count;}if (torg==0) torg=count-1;result=new __int64[candg*torg+2];for(i=1;i<=candg*torg+1;i++)result[i]=0;for(i=1;i<=candg;i++){for(j=1;j<=torg;j++){result[i+j-1]+=get_cand[i]*get_tor[j];result[i+j]+=result[i+j-1]/1000000000;result[i+j-1]=result[i+j-1]%1000000000;}}i=candg*torg+1;str.clear();while(result[i]==0) i--;temp=result[i];while(temp){ch.push_back(temp%10+48);str.insert(0,ch);ch.clear();temp/=10;}i--;xresult.append(str);str.clear();while(i>=1){temp=result[i--];while(temp){ch.push_back(temp%10+48);str.insert(0,ch);ch.clear();temp/=10;}slen=(int)str.length();if (slen<9){for(j=1;j<=9-slen;j++){str.insert(0,"0");}}xresult.append(str);str.clear();}if (xlen>0){slen=xresult.length();xresult.push_back(' ');count=0;for(i=xresult.length()-1;i>=0;i--){xresult[i]=xresult[i-1];count++;if (count==xlen) {xresult[i-1]='.';break;}if (count<xlen&&i==1) {xresult.insert(0,"0");i++;}}if (i==1) xresult.insert(0,"0");}de0(xresult);delete[] result;//(比赛时可以考虑不释放以节省时间)delete[] get_cand;delete[] get_tor;return xresult;}int main(){string s,t;while(cin>>s>>t)cout<<multiplication(s,t)<<endl;return 0;}大整数乘法/****** Big Number Multiplication *********************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define MAX 1000/******************************************************************/ void reverse(char *from, char *to ){int len=strlen(from);int i;for(i=0;i<len;i++)to[i]=from[len-i-1];to[len]='\0';}/******************************************************************/void call_mult(char *first,char *sec,char *result){char F[MAX],S[MAX],temp[MAX];int f_len,s_len,f,s,r,t_len,hold,res;f_len=strlen(first);s_len=strlen(sec);reverse(first,F);reverse(sec,S);t_len=f_len+s_len;r=-1;for(f=0;f<=t_len;f++)temp[f]='0';temp[f]='\0';for(s=0;s<s_len;s++){hold=0;for(f=0;f<f_len;f++){res=(F[f]-'0')*(S[s]-'0') + hold+(temp[f+s]-'0');temp[f+s]=res%10+'0';hold=res/10;if(f+s>r) r=f+s;}while(hold!=0){res=hold+temp[f+s]-'0';hold=res/10;temp[f+s]=res%10+'0';if(r<f+s) r=f+s;f++;}}for(;r>0 && temp[r]=='0';r--);temp[r+1]='\0';reverse(temp,result);}/***************************************************************/int main(){char fir[MAX],sec[MAX],res[MAX];while(scanf("%s%s",&fir,&sec)==2){call_mult(fir,sec,res);int len=strlen(res);for(int i=0;i<len;i++)printf("%c",res[i]);printf("\n");}return 0;}大整数除法//***** Big Number division *********************//#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define MAX 1000/*******************************************************************/ int call_div(char *number,long div,char *result){int len=strlen(number);int now;long extra;char Res[MAX];for(now=0,extra=0;now<len;now++){extra=extra*10 + (number[now]-'0');Res[now]=extra / div +'0';extra%=div;}Res[now]='\0';for(now=0;Res[now]=='0';now++);strcpy(result, &Res[now]);if(strlen(result)==0)strcpy(result, "0");return extra;}/*******************************************************************/ int main(){char fir[MAX],res[MAX];long sec,remainder;while(scanf("%s%ld",&fir,&sec)==2){if(sec==0) printf("Divide by 0 error\n");else{remainder=call_div(fir,sec,res); int len=strlen(res);for(int i=0;i<len;i++)printf("%c",res[i]);printf("\t%ld",remainder); //余数 printf("\n");}}return 0;}大整数加法#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define MAX 1000void reverse(char *from, char *to ){int len=strlen(from);int l;for(l=0;l<len;l++)to[l]=from[len-l-1];to[len]='\0';}void call_sum(char *first, char *sec, char *result){char F[MAX], S[MAX], Res[MAX];int f,s,sum,extra,now;f=strlen(first);s=strlen(sec);reverse(first,F);reverse(sec,S);for(now=0,extra=0;(now<f && now<s);now++){sum=(F[now]-'0') + (S[now]-'0') + extra; Res[now]=sum%10 +'0';extra= sum/10;}for(;now<f;now++){sum=F[now] + extra-'0';Res[now]=sum%10 +'0';extra=sum/10;}for(;now<s;now++){sum=F[now] + extra-'0';Res[now]=sum%10 +'0';extra=sum/10;}if(extra!=0) Res[now++]=extra+'0';Res[now]='\0';if(strlen(Res)==0) strcpy(Res,"0");reverse(Res,result);}int main(){char fir[MAX],sec[MAX],res[MAX];while(scanf("%s%s",&fir,&sec)==2){call_sum(fir,sec,res);int len=strlen(res);for(int i=0;i<len;i++) printf("%c",res[i]);printf("\n");}return 0;}大整数减法/***** Big Number Subtraction *******************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define MAX 1000/*******************************************************************/ void reverse(char *from, char *to ){int len=strlen(from);int l;for(l=0;l<len;l++)to[l]=from[len-l-1];to[len]='\0';}int call_minus(char *large, char *small, char *result){char L[MAX], S[MAX];int l,s,now,hold,diff;l=strlen(large);s=strlen(small);bool sign = 0;if(l<s){strcpy(result,large);strcpy(large,small);strcpy(small,result);now=l; l=s; s=now;sign = 1;}//return 0;if(l==s){if(strcmp(large, small)<0){strcpy(result,large);strcpy(large,small);strcpy(small,result);now=l; l=s; s=now;sign =1;}//return 0;}reverse(large,L);reverse(small,S);for(;s<l;s++)S[s]='0';S[s]='\0';for(now=0,hold=0;now<l;now++){diff=L[now]-(S[now]+hold);if(diff<0){hold=1;result[now]=10+diff+'0'; }else{result[now]=diff+'0';hold=0;}}for(now=l-1;now>0;now--){if(result[now]!='0')break;}result[now+1]='\0';reverse(result,L);strcpy(result,L);//return 1;return sign;}int main(){char fir[MAX],sec[MAX],res[MAX];while(scanf("%s%s",&fir,&sec)==2){if(call_minus(fir,sec,res)==1) printf("-");int len = strlen(res);for(int i=0;i<len;i++)printf("%c",res[i]);printf("\n");}return 0;}大整数开平方根//****** Big Number Sqrt ************************//#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define MAX 1000/******************************************************************/ void reverse(char *from, char *to ){int len=strlen(from);int i;for(i=0;i<len;i++)to[i]=from[len-i-1];to[len]='\0';}/****************************************************************/ int call_minus(char *large, char *small, char *result){char L[MAX], S[MAX];int l,s,now,hold,diff;l=strlen(large);s=strlen(small);if(l<s)return 0;if(l==s){if(strcmp(large, small)<0)return 0;}reverse(large,L);reverse(small,S);for(;s<l;s++)S[s]='0';S[s]='\0';for(now=0,hold=0;now<l;now++){diff=L[now]-(S[now]+hold);if(diff<0){hold=1;result[now]=10+diff+'0';}else{result[now]=diff+'0';hold=0;}}for(now=l-1;now>0;now--){if(result[now]!='0')break;}result[now+1]='\0';reverse(result,L);strcpy(result,L);return 1;}/******************************************************************/ void call_mult(char *first,char *sec,char *result){char F[MAX],S[MAX],temp[MAX];int f_len,s_len,f,s,r,t_len,hold,res;f_len=strlen(first);s_len=strlen(sec);reverse(first,F);reverse(sec,S);t_len=f_len+s_len;r=-1;for(f=0;f<=t_len;f++)temp[f]='0';temp[f]='\0';for(s=0;s<s_len;s++){hold=0;for(f=0;f<f_len;f++){res=(F[f]-'0')*(S[s]-'0') + hold+(temp[f+s]-'0');temp[f+s]=res%10+'0';hold=res/10;if(f+s>r) r=f+s;}while(hold!=0){res=hold+temp[f+s]-'0';hold=res/10;temp[f+s]=res%10+'0';if(r<f+s) r=f+s;f++;}}for(;r>0 && temp[r]=='0';r--);temp[r+1]='\0';reverse(temp,result);}/****************************************************************/ void call_sqrt(char *number,char *result,char *extra){int num,start,e,mul,l,r=0,len;char left[MAX],after[MAX];char who[5],temp[MAX],two[5];len=strlen(number);if(len%2==0){num=10*(number[0]-'0') + number[1]-'0';start=2;}else{num=number[0]-'0';start=1;}mul=(int) sqrt(num);result[0]=mul+'0';result[1]='\0';if(num-mul*mul ==0)extra[0]='\0';elsesprintf(extra,"%d",num-mul*mul);for(;start<len;start+=2){e=strlen(extra);extra[e]=number[start];extra[e+1]=number[start+1];extra[e+2]='\0';two[0]='2';two[1]='\0';call_mult(result,two,left);l=strlen(left);for(mul=9;mul>=0;mul--){who[0]=mul+'0';who[1]='\0';strcat(left,who);call_mult(left,who,after);if(call_minus(extra,after,temp)==1){result[++r]=mul+'0';result[r+1]='\0';strcpy(extra,temp);break;}elseleft[l]='\0';}}result[++r]='\0';}/******************************************************************/ int main(){char fir[MAX],ex[MAX],res[MAX];while(scanf("%s",&fir)==1){call_sqrt(fir,res,ex);int len=strlen(res);for(int i=0;i<len;i++) printf("%c",res[i]);printf("\n");}return 0;}孩子报数问题:#include<stdio.h>#include<string.h>typedef struct{char name[16];}Name;int main(){Name child[65];int n,count,i,j,k;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%s",&child[i].name);}scanf("%d,%d",&count,&k);for(i=n;i>=2;--i){count=(count+k-1)%i;if (count==0) count=i;printf("%s\n",child[count].name);for(j=count;j<i;++j){strcpy(child[j].name,child[j+1].name);}}printf("%s\n",child[1].name);return 0;}统计难题:Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).输入输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.注意:本题只有一组测试数据,处理到文件结束.输出对于每个提问,给出以该字符串为前缀的单词的数量.样例输入bananabandbeeabsoluteacmbabbandabc样例输出231字典树解决:#include<iostream>#include<string.h>using namespace std;typedef struct Node{char letter;bool la;struct Node *child;struct Node *brother;int count;}Elem;void creat(Elem *head,char *word){Elem *p,*q,*r;int i;bool suc;p=head;for(i=0;i<(int)strlen(word);i++){suc=false;q=p->child;r=q;while(q){r=q;if (q->letter==word[i]) {suc=true;p=q;p->count++;break;}q=q->brother;}if (suc) continue;q=new Elem;q->letter=word[i];q->count=1;q->brother=NULL;q->child=NULL;q->la=false;if (!p->child) p->child=q;if (r) r->brother=q;p=q;}}int find_1(Elem head,char *word){Elem *p,*q;int i;p=&head;for(i=0;i<(int)strlen(word);i++){q=p->child;while(q){if (q->letter==word[i]) {break;}q=q->brother;}if (!q) return 0;p=q;}return p->count;}int main(){char word[10];Elem head;head.letter=0;head.child=NULL;head.brother=NULL;=true;head.count=0;while(gets(word),strcmp(word,"")!=0){creat(&head,word);}while(scanf("%s",word)!=EOF){printf("%d\n",find_1(head,word));}return 0;}21。

C++大整数类模板

C++大整数类模板

C++⼤整数类模板参考:http://172.21.85.56/oj/resource/reportdetail?report_id=1678⽀持=、abs()、pow()、+=、-=*=、/=、%=、+、-、*、/++、--、⼤⼩⽐较、输⼊输出流其中涉及除法或者模运算的可抛出除数为0的异常#include<iostream>#include<vector>#include<deque>#include<string.h>#include<math.h>#include<stdio.h>#include<algorithm>#include<string>using namespace std;class DividedByZeroException {};class BigInteger {private:vector<char> digits;bool sign; // true for positive, false for negitivevoid trim(); // remove zeros in tail, but if the value is 0, keep only one:)public:BigInteger(int); // construct with a int integerBigInteger(string&) ;BigInteger();BigInteger(const BigInteger&);BigInteger operator=(const BigInteger& op2);BigInteger abs() const;BigInteger pow(int a);//binary operatorsfriend BigInteger operator+=(BigInteger&, const BigInteger&);friend BigInteger operator-=(BigInteger&, const BigInteger&);friend BigInteger operator*=(BigInteger&, const BigInteger&);friend BigInteger operator/=(BigInteger&, const BigInteger&) throw(DividedByZeroException);friend BigInteger operator%=(BigInteger&, const BigInteger&) throw(DividedByZeroException);friend BigInteger operator+(const BigInteger&, const BigInteger&);friend BigInteger operator-(const BigInteger&, const BigInteger&);friend BigInteger operator*(const BigInteger&, const BigInteger&);friend BigInteger operator/(const BigInteger&, const BigInteger&) throw(DividedByZeroException);friend BigInteger operator%(const BigInteger&, const BigInteger&) throw(DividedByZeroException);//uniary operatorsfriend BigInteger operator-(const BigInteger&); //negativefriend BigInteger operator++(BigInteger&); //++vfriend BigInteger operator++(BigInteger&, int); //v++friend BigInteger operator--(BigInteger&); //--vfriend BigInteger operator--(BigInteger&, int); //v--friend bool operator>(const BigInteger&, const BigInteger&);friend bool operator<(const BigInteger&, const BigInteger&);friend bool operator==(const BigInteger&, const BigInteger&);friend bool operator!=(const BigInteger&, const BigInteger&);friend bool operator>=(const BigInteger&, const BigInteger&);friend bool operator<=(const BigInteger&, const BigInteger&);friend ostream& operator<<(ostream&, const BigInteger&); //print the BigIntegerfriend istream& operator>>(istream&, BigInteger&); // input the BigIntegerpublic:static const BigInteger ZERO;static const BigInteger TEN;};const BigInteger BigInteger::ZERO = BigInteger(0);const BigInteger BigInteger::ONE = BigInteger(1);const BigInteger BigInteger::TEN = BigInteger(10);BigInteger::BigInteger() {sign = true;}BigInteger::BigInteger(int val) { // construct with a int integerif (val >= 0) {sign = true;}else {sign = false;val *= (-1);}do {digits.push_back((char)(val % 10));val /= 10;} while (val != 0);}BigInteger::BigInteger(string& def) {sign = true;for (string::reverse_iterator iter = def.rbegin() ; iter < def.rend(); iter++) { char ch = (*iter);if (iter == def.rend() - 1) {if (ch == '+') {break;}if (ch == '-') {sign = false;break;}}digits.push_back((char)((*iter) - '0'));}trim();}void BigInteger::trim() {vector<char>::reverse_iterator iter = digits.rbegin();while (!digits.empty() && (*iter) == 0) {digits.pop_back();iter = digits.rbegin();}if (digits.size() == 0) {sign = true;digits.push_back(0);}}BigInteger::BigInteger(const BigInteger& op2) {sign = op2.sign;digits = op2.digits;}BigInteger BigInteger::operator=(const BigInteger& op2) {digits = op2.digits;sign = op2.sign;return (*this);}BigInteger BigInteger::abs() const {if (sign) {return *this;else {return -(*this);}}BigInteger BigInteger::pow(int a) {BigInteger res(1);for (int i = 0; i < a; i++) {res *= (*this);}return res;}//binary operatorsBigInteger operator+=(BigInteger& op1, const BigInteger& op2) {if (op1.sign == op2.sign) { //只处理相同的符号的情况,异号的情况给-处理 vector<char>::iterator iter1;vector<char>::const_iterator iter2;iter1 = op1.digits.begin();iter2 = op2.digits.begin();char to_add = 0; //进位while (iter1 != op1.digits.end() && iter2 != op2.digits.end()) {(*iter1) = (*iter1) + (*iter2) + to_add;to_add = ((*iter1) > 9); // ⼤于9进⼀位(*iter1) = (*iter1) % 10;iter1++;iter2++;}while (iter1 != op1.digits.end()) { //(*iter1) = (*iter1) + to_add;to_add = ((*iter1) > 9);(*iter1) %= 10;iter1++;}while (iter2 != op2.digits.end()) {char val = (*iter2) + to_add;to_add = (val > 9) ;val %= 10;op1.digits.push_back(val);iter2++;}if (to_add != 0) {op1.digits.push_back(to_add);}return op1;}else {if (op1.sign) {return op1 -= (-op2);}else {return op1 = op2 - (-op1);}}}BigInteger operator-=(BigInteger& op1, const BigInteger& op2) {if (op1.sign == op2.sign) { //只处理相同的符号的情况,异号的情况给+处理if (op1.sign) {if (op1 < op2) { // 2 - 3return op1 = -(op2 - op1);}}else {if (-op1 > -op2) { // (-3)-(-2) = -(3 - 2)return op1 = -((-op1) - (-op2));}else { // (-2)-(-3) = 3 - 2return op1 = (-op2) - (-op1);}vector<char>::iterator iter1;vector<char>::const_iterator iter2;iter1 = op1.digits.begin();iter2 = op2.digits.begin();char to_substract = 0; //借位while (iter1 != op1.digits.end() && iter2 != op2.digits.end()) {(*iter1) = (*iter1) - (*iter2) - to_substract;to_substract = 0;if ((*iter1) < 0) {to_substract = 1;(*iter1) += 10;}iter1++;iter2++;}while (iter1 != op1.digits.end()) {(*iter1) = (*iter1) - to_substract;to_substract = 0;if ((*iter1) < 0) {to_substract = 1;(*iter1) += 10;}else {break;}iter1++;}op1.trim();return op1;}else {if (op1 > BigInteger::ZERO) {return op1 += (-op2);}else {return op1 = -(op2 + (-op1));}}}BigInteger operator*=(BigInteger& op1, const BigInteger& op2) {BigInteger result(0);if (op1 == BigInteger::ZERO || op2 == BigInteger::ZERO) {result = BigInteger::ZERO;}else {vector<char>::const_iterator iter2 = op2.digits.begin();while (iter2 != op2.digits.end()) {if (*iter2 != 0) {deque<char> temp(op1.digits.begin(), op1.digits.end());char to_add = 0;deque<char>::iterator iter1 = temp.begin();while (iter1 != temp.end()) {(*iter1) *= (*iter2);(*iter1) += to_add;to_add = (*iter1) / 10;(*iter1) %= 10;iter1++;}if (to_add != 0) {temp.push_back(to_add);}int num_of_zeros = iter2 - op2.digits.begin();while (num_of_zeros--) {temp.push_front(0);BigInteger temp2;temp2.digits.insert(temp2.digits.end(), temp.begin(), temp.end());temp2.trim();result = result + temp2;}iter2++;}result.sign = ((op1.sign && op2.sign) || (!op1.sign && !op2.sign));}op1 = result;return op1;}BigInteger operator/=(BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) { if (op2 == BigInteger::ZERO) {throw DividedByZeroException();}BigInteger t1 = op1.abs(), t2 = op2.abs();if (t1 < t2) {op1 = BigInteger::ZERO;return op1;}//现在 t1 > t2 > 0//只需将 t1/t2的结果交给result就可以了deque<char> temp;vector<char>::reverse_iterator iter = t1.digits.rbegin();BigInteger temp2(0);while (iter != t1.digits.rend()) {temp2 = temp2 * BigInteger::TEN + BigInteger((int)(*iter));char s = 0;while (temp2 >= t2) {temp2 = temp2 - t2;s = s + 1;}temp.push_front(s);iter++;}op1.digits.clear();op1.digits.insert(op1.digits.end(), temp.begin(), temp.end());op1.trim();op1.sign = ((op1.sign && op2.sign) || (!op1.sign && !op2.sign));return op1;}BigInteger operator%=(BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) { return op1 -= ((op1 / op2) * op2);}BigInteger operator+(const BigInteger& op1, const BigInteger& op2) {BigInteger temp(op1);temp += op2;return temp;}BigInteger operator-(const BigInteger& op1, const BigInteger& op2) {BigInteger temp(op1);temp -= op2;return temp;}BigInteger operator*(const BigInteger& op1, const BigInteger& op2) {BigInteger temp(op1);temp *= op2;return temp;}BigInteger operator/(const BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) { BigInteger temp(op1);temp /= op2;return temp;}BigInteger operator%(const BigInteger& op1, const BigInteger& op2) throw(DividedByZeroException) { BigInteger temp(op1);temp %= op2;return temp;}//uniary operatorsBigInteger operator-(const BigInteger& op) { //negativeBigInteger temp = BigInteger(op);temp.sign = !temp.sign;return temp;}BigInteger operator++(BigInteger& op) { //++vop += BigInteger::ONE;return op;}BigInteger operator++(BigInteger& op, int x) { //v++BigInteger temp(op);++op;return temp;}BigInteger operator--(BigInteger& op) { //--vop -= BigInteger::ONE;return op;}BigInteger operator--(BigInteger& op, int x) { //v--BigInteger temp(op);--op;return temp;}bool operator<(const BigInteger& op1, const BigInteger& op2) {if (op1.sign != op2.sign) {return !op1.sign;}else {if (op1.digits.size() != op2.digits.size())return (op1.sign && op1.digits.size() < op2.digits.size())|| (!op1.sign && op1.digits.size() > op2.digits.size());vector<char>::const_reverse_iterator iter1, iter2;iter1 = op1.digits.rbegin();iter2 = op2.digits.rbegin();while (iter1 != op1.digits.rend()) {if (op1.sign && *iter1 < *iter2) {return true;}if (op1.sign && *iter1 > *iter2) {return false;}if (!op1.sign && *iter1 > *iter2) {return true;}if (!op1.sign && *iter1 < *iter2) {return false;}iter1++;iter2++;}return false;}}bool operator==(const BigInteger& op1, const BigInteger& op2) {if (op1.sign != op2.sign || op1.digits.size() != op2.digits.size()) {return false;}vector<char>::const_iterator iter1, iter2;iter1 = op1.digits.begin();iter2 = op2.digits.begin();while (iter1 != op1.digits.end()) {return false;}iter1++;iter2++;}return true;}bool operator!=(const BigInteger& op1, const BigInteger& op2) {return !(op1 == op2);}bool operator>=(const BigInteger& op1, const BigInteger& op2) {return (op1 > op2) || (op1 == op2);}bool operator<=(const BigInteger& op1, const BigInteger& op2) {return (op1 < op2) || (op1 == op2);}bool operator>(const BigInteger& op1, const BigInteger& op2) {return !(op1 <= op2);}ostream& operator<<(ostream& stream, const BigInteger& val) { //print the BigInteger if (!val.sign) {stream << "-";}for (vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++) { stream << (char)((*iter) + '0');}return stream;}istream& operator>>(istream& stream, BigInteger& val) { //Input the BigIntegerstring str;stream >> str;val = BigInteger(str);return stream;}int main() {BigInteger A;int B;BigInteger C = 888;cin >>B;cout << "A-B:" << A - B << endl;cout << "A+B:" << A + B << endl;cout << "A*B:" << A*B << endl;cout << "A/B:" << A / B << endl;cout << "A%B:" << A % B << endl;cout << A.pow(B-3) << endl;A++;cout << "A++:" << A << endl;A--;cout << "A--:" << A << endl;cout << "++B:" << ++B << endl;cout << "--B:" << --B << endl;cout << "C:" << C << endl;}View Code。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
return t>0;
}
void add(bignum_t a,const bignum_t b){
int i;
for (i=1;i<=b[0];i++)
if ((a[i]+=b[i])>=DEPTH)
a[i]-=DEPTH,a[i+1]++;
if (b[0]>=a[0])
a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH;
for (;a[i]<0;a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++);
for (;!a[a[0]]&&a[0]>1;a[0]--);
char buf[MAX*DIGIT+1],ch;
int i,j;
memset((void*)a,0,sizeof(bignum_t));
if (!(is>>buf)) return 0;
for (a[0]=strlen(buf),i=a[0]/2-1;i>=0;i--)
ch=buf[i],buf[i]=buf[a[0]-1-i],buf[a[0]-1-i]=ch;
os<<a[i]/j%10;
}
int comp(const bignum_t a,const bignum_t b){
int i;
if (a[0]!=b[0])
return a[0]-b[0];
for (i=a[0];i;i--)
if (a[i]!=b[i])
return a[i]-b[i];
}
void div(bignum_t c,bignum_t a,const bignum_t b){
int h,l,m,i;
memset((void*)c,0,sizeof(bignum_t));
c[0]=(b[0]<a[0]+1)?(a[0]-b[0]+2):1;
for (i=c[0];i;sub(a,b,c[i]=m,i-1),i--)
for (a[0]=(a[0]+DIGIT-1)/DIGIT,j=strlen(buf);j<a[0]*DIGIT;buf[j++]='0');
for (i=1;i<=a[0];i++)
for (a[i]=0,j=0;j<DIGIT;j++)
a[i]=a[i]*10+buf[i*DIGIT-1-j]-'0';
}
void comp(int* a,const int l,const int h,const int d){
int i,j,t;
for (i=l;i<=h;i++)
for (t=i,j=2;t>1;j++)
while (!(t%j))
a[j]+=d,t/=j;
return ret%10;
}
int zeronum(const bignum_t a){
int ret,t;
for (ret=0;!a[ret+1];ret++);
for (t=a[ret+1],ret*=DIGIT;!(t%10);t/=10,ret++);
return ret;
} Biblioteka void convert(int* a,const int h,bignum_t b){
int i,j,t=1;
memset(b,0,sizeof(bignum_t));
for (b[0]=b[1]=1,i=2;i<=h;i++)
if (a[i])
for (j=a[i];j;t*=i,j--)
for (;a[a[0]]>=DEPTH;a[a[0]+1]=a[a[0]]/DEPTH,a[a[0]]%=DEPTH,a[0]++);
}
void sub(bignum_t a,const bignum_t b){
int i;
for (i=1;i<=b[0];i++)
if ((a[i]-=b[i])<0)
a[0]=b[0];
else
for (;a[i]>=DEPTH&&i<a[0];a[i]-=DEPTH,i++,a[i]++);
a[0]+=(a[a[0]+1]>0);
}
void add(bignum_t a,const int b){
int i=1;
for (a[1]+=b;a[i]>=DEPTH&&i<a[0];a[i+1]+=a[i]/DEPTH,a[i]%=DEPTH,i++);
for (h=DEPTH-1,l=0,m=(h+l+1)>>1;h>l;m=(h+l+1)>>1)
if (comp(b,m,i-1,a)) h=m-1;
else l=m;
for (;!c[c[0]]&&c[0]>1;c[0]--);
c[0]=c[0]>1?c[0]:1;
}
void mul(bignum_t c,const bignum_t a,const bignum_t b){
int i,j;
memset((void*)c,0,sizeof(bignum_t));
for (c[0]=a[0]+b[0]-1,i=1;i<=a[0];i++)
for (j=1;j<=b[0];j++)
for (;!a[a[0]]&&a[0]>1;a[0]--);
}
void sub(bignum_t a,const bignum_t b,const int c,const int d){
int i,O=b[0]+d;
for (i=1+d;i<=O;i++)
if ((a[i]-=b[i-d]*c)<0)
for (ret=(a[0]-1)*DIGIT,t=a[a[0]];t;t/=10,ret++);
return ret>0?ret:1;
}
int digit(const bignum_t a,const int b){
int i,ret;
for (ret=a[(b-1)/DIGIT+1],i=(b-1)%DIGIT;i;ret/=10,i--);
#include <iostream.h>
#include <string.h>
#define DIGIT 4
#define DEPTH 10000
#define MAX 100
typedef int bignum_t[MAX+1];
int read(bignum_t a,istream& is=cin){
}
int comp(const bignum_t a,const int c,const int d,const bignum_t b){
int i,t=0,O=-DEPTH*2;
if (b[0]-a[0]<d&&c)
return 1;
for (i=b[0];i>d;i--){
a[i+1]--,a[i]+=DEPTH;
for (;a[i]<0;a[i]+=DEPTH,i++,a[i]--);
for (;!a[a[0]]&&a[0]>1;a[0]--);
}
void sub(bignum_t a,const int b){
int i=1;
for (a[1]-=b;a[i]<0;a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++);
if (t*i>DEPTH)
mul(b,t),t=1;
mul(b,t);
}
void combination(bignum_t a,int m,int n){
int* t=new int[m+1];
memset((void*)t,0,sizeof(int)*(m+1));
if (comp(b,m,i-1,a)) h=m-1;
else l=m;
for (;!b[b[0]]&&b[0]>1;b[0]--);
for (i=1;i<=b[0];b[i++]>>=1);
}
int length(const bignum_t a){
int t,ret;
相关文档
最新文档