ACM_simple
acm 算法模板 适合初学者使用
三角形面积计算 (1)字典树模板 (2)求线段所在直线 (5)求外接圆 (5)求内接圆 (6)判断点是否在直线上 (8)简单多边形面积计算公式 (8)stein算法求最大共约数 (9)最长递增子序列模板——o(nlogn算法实现) (9)判断图中同一直线的点的最大数量 (10)公因数和公倍数 (12)已知先序中序求后序 (12)深度优先搜索模板 (13)匈牙利算法——二部图匹配BFS实现 (15)带输出路径的prime算法 (17)prime模板 (18)kruskal模板 (19)dijsktra (22)并查集模板 (23)高精度模板 (24)三角形面积计算//已知三条边和外接圆半径,公式为s = a*b*c/(4*R)double GetArea(double a, double b, double c, double R){return a*b*c/4/R;}//已知三条边和内接圆半径,公式为s = prdouble GetArea(double a, double b, double c, double r){return r*(a+b+c)/2;}//已知三角形三条边,求面积double GetArea(doule a, double b, double c){double p = (a+b+c)/2;return sqrt(p*(p-a)*(p-b)*(p-c));}//已知道三角形三个顶点的坐标struct Point{double x, y;Point(double a = 0, double b = 0){x = a; y = b;}};double GetArea(Point p1, Point p2, Point p3){double t =-p2.x*p1.y+p3.x*p1.y+p1.x*p2.y-p3.x*p2.y-p1.x*p3.y+p2.x*p3.y;if(t < 0) t = -t;return t/2;}字典树模板#include <stdio.h>#include <string.h>#include <memory.h>#define BASE_LETTER 'a'#define MAX_TREE 35000#define MAX_BRANCH 26struct{int next[MAX_BRANCH]; //记录分支的位置int c[MAX_BRANCH]; //查看分支的个数int flag; //是否存在以该结点为终止结点的东东,可以更改为任意的属性}trie[MAX_TREE];int now;void init(){now = 0;memset(&trie[now], 0, sizeof(trie[now]));now ++;}int add (){memset(&trie[now], 0, sizeof(trie[now]));return now++;}int insert( char *str){int pre = 0, addr;while( *str != 0 ){addr = *str - BASE_LETTER;if( !trie[pre].next[addr] )trie[pre].next[addr] = add();trie[pre].c[addr]++;pre = trie[pre].next[addr];str ++;}trie[pre].flag = 1;return pre;}int search( char *str ){int pre = 0, addr;while( *str != 0 ){addr = *str - BASE_LETTER;if ( !trie[pre].next[addr] )return 0;pre = trie[pre].next[addr];str ++;}if( !trie[pre].flag )return 0;return pre;}pku2001题,源代码:void check( char *str ){int pre = 0, addr;while(*str != 0){addr = *str - BASE_LETTER;if( trie[pre].c[addr] == 1) {printf("%c\n", *str);return;}printf("%c", *str);pre = trie[pre].next[addr];str ++;}printf("\n");}char input[1001][25];int main(){int i = 0,j;init();while(scanf("%s", input[i]) != EOF){getchar();insert(input[i]);i++;}for(j = 0; j < i; j ++){printf("%s ", input[j]);check(input[j]);}return 0;}求线段所在直线//*****************************线段所在的直线struct Line{double a, b, c;};struct Point{double x, y;}Line GetLine(Point p1, Point p2){//ax+by+c = 0返回直线的参数Line line;line.a = p2.y - p1.y;line.b = p1.x - p2.x;line.c = p2.x*p1.y - p1.x*p2.y;return line;}求外接圆//***************已知三角形三个顶点坐标,求外接圆的半径和坐标********************struct Point{double x, y;Point(double a = 0, double b = 0){x = a; y = b;}};struct TCircle{double r;Point p;}double distance(Point p1, Point p2){return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));}double GetArea(doule a, double b, double c){double p = (a+b+c)/2;return sqrt(p*(p-a)*(p-b)*(p-c));}TCircle GetTCircle(Point p1, Point p2, Point p3){double a, b, c;double xa,ya, xb, yb, xc, yc, c1, c2;TCircle tc;a = distance(p1, p2);b = distance(p2, p3);c = distance(p3, p1);//求半径tc.r = a*b*c/4/GetArea(a, b, c);//求坐标xa = p1.x; ya = p1.b;xb = p2.x; yb = p2.b;xc = p3.x; yc = p3.b;c1 = (xa*xa + ya*ya - xb*xb - yb*yb)/2;c2 = (xa*xa + ya*ya - xc*xc - yc*yc)/2;tc.p.x = (c1*(ya-yc) - c2*(ya-yb))/((xa-xb)*(ya-yc) - (xa-xc)*(ya-yb)); tc.p.y = (c1*(xa-xc) - c2*(xa-xb))/((ya-yb)*(xa-xc) - (ya-yc)*(xa-xb));return tc;}求内接圆struct Point{double x, y;Point(double a = 0, double b = 0){x = a; y = b;}};struct TCircle{double r;Point p;}double distance(Point p1, Point p2){return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));}double GetArea(doule a, double b, double c){double p = (a+b+c)/2;return sqrt(p*(p-a)*(p-b)*(p-c));}TCircle GetTCircle(Point p1, Point p2, Point p3){double a, b, c;double xa,ya, xb, yb, xc, yc, c1, c2, f1, f2;double A,B,C;TCircle tc;a = distance(p1, p2);b = distance(p3, p2);c = distance(p3, p1);//求半径tc.r = 2*GetArea(a, b, c)/(a+b+c);//求坐标A = acos((b*b+c*c-a*a)/(2*b*c));B = acos((a*a+c*c-b*b)/(2*a*c));C = acos((a*a+b*b-c*c)/(2*a*b));p = sin(A/2); p2 = sin(B/2); p3 = sin(C/2);xb = p1.x; yb = p1.b;xc = p2.x; yc = p2.b;xa = p3.x; ya = p3.b;f1 = ( (tc.r/p2)*(tc.r/p2) - (tc.r/p)*(tc.r/p) + xa*xa - xb*xb + ya*ya - yb*yb)/2;f2 = ( (tc.r/p3)*(tc.r/p3) - (tc.r/p)*(tc.r/p) + xa*xa - xc*xc + ya*ya - yc*yc)/2;tc.p.x = (f1*(ya-yc) - f2*(ya-yb))/((xa-xb)*(ya-yc)-(xa-xc)*(ya-yb)); tc.p.y = (f1*(xa-xc) - f2*(xa-xb))/((ya-yb)*(xa-xc)-(ya-yc)*(xa-xb));return tc;}判断点是否在直线上//**************判断点是否在直线上********************* //判断点p是否在直线[p1,p2]struct Point{double x,y;};bool isPointOnSegment(Point p1, Point p2, Point p0){//叉积是否为0,判断是否在同一直线上if((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y) != 0)return false;//判断是否在线段上if((p0.x > p1.x && p0.x > p2.x) || (p0.x < p1.x && p0.x < p2.x)) return false;if((p0.y > p1.y && p0.y > p1.y) || (p0.y < p1.y && p0.y < p2.y)) return false;return true;}简单多边形面积计算公式struct Point{double x, y;Point(double a = 0, double b = 0){x = a; y = b;}};Point pp[10];double GetArea(Point *pp, int n){//n为点的个数,pp中记录的是点的坐标int i = 1;double t = 0;for(; i <= n-1; i++)t += pp[i-1].x*pp[i].y - pp[i].x*pp[i-1].y;t += pp[n-1].x*pp[0].y - pp[0].x*pp[n-1].y;if(t < 0) t = -t;return t/2;}stein算法求最大共约数int gcd(int a,int b){if (a == 0) return b;if (b == 0) return a;if (a % 2 == 0 && b % 2 == 0) return 2 * gcd(a/2,b/2); else if (a % 2 == 0) return gcd(a/2,b);else if (b % 2 == 0) return gcd(a,b/2);else return gcd(abs(a-b),min(a,b));}最长递增子序列模板——o(nlogn算法实现)#include <stdio.h>#define MAX 40000int array[MAX], B[MAX];int main(){int count,i,n,left,mid,right,Blen=0,num;scanf("%d",&count); //case的个数while(count--){scanf("%d",&n); //每组成员的数量Blen = 0;for(i=1;i<=n;i++)scanf("%d",&array[i]); //读入每个成员for(i=1;i<=n;i++){num = array[i];left = 1;right = Blen;while(left<=right){mid = (left+right)/2;if(B[mid]<num)left = mid+1;elseright = mid-1;}B[left] = num;if(Blen<left)Blen++;}printf("%d\n",Blen);//输出结果}return 1;}判断图中同一直线的点的最大数量#include <iostream>#include <cstdio>#include <memory>using namespace std;#define MAX 1010 //最大点的个数struct point{int x,y;}num[MAX];int used[MAX][MAX*2]; //条件中点的左边不会大于1000,just equal MAX int countN[MAX][MAX*2];#define abs(a) (a>0?a:(-a))int GCD(int x, int y){int temp;if(x < y){temp = x; x = y; y = temp;}while(y != 0){temp = y;y = x % y;x = temp;}return x;}int main(){int n,i,j;int a,b,d,ans;while(scanf("%d", &n)==1){//initeans = 1;memset(used, 0, sizeof(used));memset(countN, 0, sizeof(countN));//readfor(i = 0; i < n; i++)scanf("%d%d", &num[i].x, &num[i].y);for(i = 0; i < n-1; i++){for(j = i+1; j < n; j++){b = num[j].y-num[i].y;a = num[j].x-num[i].x;if(a < 0) //这样可以让(2,3)(-2,-3)等价{a = -a; b = -b;}d = GCD(a,abs(b));a /= d;b /= d; b += 1000;//条件中点的左边不会大于1000if(used[a][b] != i+1){used[a][b] = i+1;countN[a][b] = 1;}else{countN[a][b]++;if(ans < countN[a][b])ans = countN[a][b];}}//for}//forprintf("%d\n", ans+1);}return 0;}公因数和公倍数int GCD(int x, int y){int temp;if(x < y){temp = x; x = y; y = temp;}while(y != 0){temp = y;y = x % y;x = temp;}return x;}int beishu(int x, int y){return x * y / GCD(x,y);}已知先序中序求后序#include <iostream>#include <string>using namespace std;string post;void fun(string pre, string mid){if(pre == "" || mid == "") return;int i = mid.find(pre[0]);fun(pre.substr(1,i), mid.substr(0,i));fun(pre.substr(i+1, (int)pre.length()-i-1), mid.substr(i+1, (int)mid.length()-i-1));post += pre[0];}int main(){string pre, mid;while(cin >> pre){cin >> mid;post.erase();fun(pre, mid);cout << post << endl;}return 0;}深度优先搜索模板int t; //t用来标识要搜索的元素int count; //count用来标识搜索元素的个数int data[m][n]; //data用来存储数据的数组//注意,数组默认是按照1……n存储,即没有第0行//下面是4个方向的搜索,void search(int x, int y){data[x][y] = *; //搜索过进行标记if(x-1 >= 1 && data[x-1][y] == t){count++;search(x-1,y);}if(x+1 <= n && data[x+1][y] == t){count++;search(x+1,y);}if(y-1 >= 1 && data[x][y-1] == t){count++;search(x,y-1);}if(y+1 <= n && data[x][y+1] == t){count++;search(x,y+1);}}//下面是8个方向的搜索void search(int x, int y){data[x][y] = *; //搜索过进行标记if(x-1 >= 1){if(data[x-1][y] == t){count++;search(x-1,y);}if(y-1 >= 1 && data[x-1][y-1] == t) {count++;search(x-1,y-1);}if(y+1 <= n && data[x-1][y+1] == t) {count++;search(x-1,y+1);}}if(x+1 <= n){if(data[x+1][y] == t){count++;search(x+1,y);}if(y-1 >= 1 && data[x+1][y-1] == t) {count++;search(x+1,y-1);}if(y+1 <= n && data[x+1][y+1] == t) {count++;search(x+1,y+1);}}if(y-1 >= 1 && data[x][y-1] == t){count++;search(x,y-1);}if(y+1 <= n && data[x][y+1] == t){count++;search(x,y+1);}}匈牙利算法——二部图匹配BFS实现//匈牙利算法实现#define MAX 310 //二部图一侧顶点的最大个数int n,m; //二分图的两个集合分别含有n和m个元素。
杭电acm题目水题英文题目、翻译及ac源代码
1040 As Easy As A+BTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 26015 Accepted Submission(s): 11054Problem DescriptionThese days, I am thinking about a question, how can I get a problem as easy as A+B? It is fairly difficulty to do such a thing. Of course, I got it after many waking nights.Give you some integers, your task is to sort these number ascending (升序).You should know how easy the problem is now!Good luck!InputInput contains multiple test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow. Each test case contains an integer N (1<=N<=1000 the number of integers to be sorted) and then N integers follow in the same line.It is guarantied that all integers are in the range of 32-int.OutputFor each case, print the sorting result, and one line one case.问题描述这些天来,我在思考一个问题,我怎样才能得到一个简单的问题,因为A + B?这是相当困难做这样的事情。
ACM(lecture_10)特殊的数
2021/6/3
26
Catalan number
2021/6/3
27
HDOJ_1134: Game of Connections
8 7 6
5
1 2 3
4
2021/6/3
28
Catalan Number
Catalan numbers (1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, ...)
trees with n+1 nodes
3 nodes:
2021/6/3
37
4 nodes: 5 nodes:
2021/6/3
38
4. the number of paths of length 2n through an n-
by-n grid that do not rise above the main diagonal
2021/6/3
6
January
2021/6/3
7
February
2021/6/3
8
March
2021/6/3
9
April
2021/6/3
10
May、June…
???
2021/6/3
11
The number series is—— 1、1、2、3、5… This is fibonacci number!
Some other pictures
2021/6/3
12
2021/6/3
13
2021/6/3
14
清华大学ACM题解
if (k==n){ //Output permutation.
for (int i-1; i<n; i++) cout<<a[i]<<" ";
}
else //a[k:n] has more than one permutation.
// Generate these recursively.
{
int a[3] = {1, 2, 3};
Perm(a, 0, 3);
return 0;
}
该程序的运行结果为
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
那么,该函数就完成了对一个数组进行全排列的操作
下面,分析该程序,我用圆圈代表每次函数的调用
对于数据的输入和输出有几道练习题
/showproblem.php?pid=1089
至
/showproblem.php?pid=1096
二、算法基础
1. 什么是算法
算法是完成特定任务的有限指令集。所有的算法必须满足下面的标准:
编辑源文件
能够提共管理程序开发的所有步骤,包括编辑的程序成为集成开发环境(integrated development evironments, IDE)。在windows系统下,使用较为广泛的有Microsoft Visual C++、Dev-Cpp等,在UNIX系统下,有Vim、emacs、eclipes等。这些程序都能提供一个较好的开发平台,使我们能够方便的开发一个程序,接下我们所要了解的都是标准C++,所有源代码都在Dev-cpp下编写,能够编译通过。
16个ACM经典算法介绍
16个ACM经典算法介绍1.深度优先(DFS)DFS是一种递归的算法,用于遍历或图、树或状态空间。
它从起始节点开始遍历,然后沿着一条路径一直遍历到最深处,然后回溯到上一个节点,继续遍历其他路径。
2.广度优先(BFS)BFS也是一种遍历算法,但与DFS不同的是,它先遍历当前节点的所有相邻节点,然后再遍历相邻节点的相邻节点,以此类推。
BFS通常使用队列数据结构,先进先出。
3. 迪杰斯特拉算法 (Dijkstra's Algorithm)迪杰斯特拉算法用于求解带权图中的最短路径问题。
它采用贪心策略,每次选择当前节点到其他节点的最短路径,从起始节点开始逐步扩展,直到到达目标节点。
4. 弗洛伊德算法 (Floyd's Algorithm)弗洛伊德算法用于求解图中所有节点之间的最短路径。
它采用动态规划的思想,通过不断更新节点之间的最短路径,最终求得所有节点之间的最短路径。
5. 快速排序 (Quick Sort)快速排序是一种高效的排序算法,它通过选择一个基准元素,将待排序列表划分为左右两部分,左边部分都小于基准元素,右边部分都大于基准元素,然后对左右两部分分别递归地进行排序。
6. 归并排序 (Merge Sort)归并排序是一种稳定的排序算法,它将待排序列表分成长度相等的两部分,然后分别对这两部分进行排序,最后将排序好的两部分再合并成一个有序列表。
7. 堆排序 (Heap Sort)堆排序利用二叉堆数据结构实现,它将待排序列表看作是一颗完全二叉树,利用堆的性质对其进行排序。
8. Prim算法 (Prim's Algorithm)Prim算法用于求解最小生成树问题,它从一个节点开始,然后逐步扩展,每次选择当前节点到其他节点的最小权值边,直到生成一棵包含所有节点的树。
9. Kruskal算法 (Kruskal's Algorithm)Kruskal算法也用于求解最小生成树问题,它通过对所有边按权重从小到大进行排序,然后逐步加入图中,直到生成一棵包含所有节点的树。
(lecture_01)初识ACM_20070925_simplePPT精品文档71页
ACM题目特点:
由于ACM竞赛题目的输入数据和输出数 据一般有多组(不定),并且格式多种 多样,所以,如何处理题目的输入输出 是对大家的一项最基本的要求。这也是 困扰初学者的一大问题。
下面,分类介绍:
21 08.01.2020
先看一个超级简单的题目:
/showproblem.php?pid=108 9
Run Time Error -- 程序运行过程中出现非正常中断。
Time Limit Exceeded
-- 运行超过时限还没有得到输出结果。
Wrong Answer -- 答案错误。
Presentation Error
-- 输出格式不对,可检查空格、回车等等细节。
Accepted -- 恭喜恭喜!
7 08.01.2020
8 08.01.2020
ACM in HDU
2019年9月,第一次参加省赛(邀请赛)
2019年5月,浙江省“舜宇”杯首届大学生程序设计大赛
2019年11~12月,第29届ACM亚洲区北京和上海赛区比赛
2019年5月,浙江省第二届“舜宇”杯大学生程序设计大 赛
少参加4~5个赛区的比赛) 另外,每学期至少有三次月赛以及适当
的练习赛
10 08.01.2020
如何比赛? 3人组队
可以携带诸如书、手册、 程序清单等参考资料; 不能携带任何可用计算机处理的软件或数据、不 能携带任何类型的通讯工具;
可能收到的反馈信息包括:
Compile Error -- 程序不能通过编译。
现在,ACM / ICPC已成为世界各国大学生中最 具影响力的国际计算机赛事。(非官方)
ACM水题题目解析
2
项目设计
• 1. 输入四个整数 • 2. 求第一个数和第二个数的差,用p表示 • 3. 求第二个数和第三个数的差,用q表示 • 4. 若p与q相等,为等差数列,计算并输出该等差数 列的第五项 • 5. 若p与q不相等,为等比数列,计算并输出等比数 列的第五项
3
项目实现
main() { int i; int num[4]; int d; int q; for (i = 0; i < 4; ++i) { scanf("%d", num + i); printf("%d ", num[i]); } d = num[1] - num[0]; q = num[2] - num[1]; if (d == q) printf("%d\n", num[3] + d); else printf("%d\n", (int)(num[3] * (num[1] * 1.0 / num[0]))); }
4
项目运行
5
ACM
项目二——数字排序问题
项目构思:
• 已知一个从1到n的无序数组,我们可以两两互换数字 的方式为该数组排序,如数组2, 3, 5, 4, 1,可以通过 三次交换得到有序数组1,2,3,4,5 • 23541 13542 13245 12345 如上面的数组,要通过三次交换,得到有序数组。 • 编程实现:输入一个1到n的无序序列,计算该序列通 过交换数字得到有序序列的最少次数。
6
项目实现 #include <stdio.h> main() { int num[100]; int len; int count=0; int i,j,k,temp; printf("请输入要输入数字的个数:"); scanf("%d",&len); for(i=0;i<len;i++) { scanf("%d",&num[i]); } for(i=0;i<len-1;i++)//求最小值 { k=i; for(j=k+1;j<len;j++) { if(num[j]<num[k]) k=j; } if(i!=k) {
acm构造题
acm构造题ACM(ACM International Collegiate Programming Contest)是一项世界范围内的大学生竞赛活动,由国际计算机协会(ACM)主办。
该竞赛的目标是提高学生的计算机编程和问题解决能力。
其中,构造题是竞赛中的一类问题,需要选手根据给定的条件构造满足特定要求的解。
构造题的难点在于具有一定的复杂性和创造性,选手需要通过推理和巧妙的设计来构建出符合要求的解。
在本文中,我们将探讨ACM构造题的一般解题思路和技巧。
首先,构造题通常以描述为主,题目中会给出某些条件和要求,要求选手构建一个满足条件且符合要求的解。
因此,在解题过程中,我们首先需要仔细阅读题目,理解所给条件和要求。
其次,我们可以尝试从简单的特殊情况入手,通过构建特殊情况的解来发现问题的规律。
例如,如果题目要求构建一个特定形状的图形,我们可以先从最简单的形状开始,逐步扩展变化,以找到构造规律。
另外,我们还可以运用数学推理来解决构造题。
数学推理在ACM竞赛中起到了至关重要的作用。
选手可以通过数学推理,构造出满足要求的解,并证明其正确性。
在解题过程中,可以尝试运用数学的知识和技巧,如数学归纳法、递推关系等,从而构建出有效的解。
此外,对于构造题中的随机性要求,选手可以运用概率论的知识给出一个满足随机性要求的解。
通过合适的随机算法,可以构造出符合要求的解,并对其进行概率分析,以保证解的有效性和随机性。
在解决构造题时,选手还需注意一些常见技巧。
例如,尽量利用给定条件和限制条件,将问题简化为更易解决的子问题;利用较小的原始素材构造出较大的解;利用排除法来确定某些条件和要求。
总结起来,ACM构造题是一类需要选手充分运用逻辑思考和创造力的问题。
在解题过程中,我们需要细致地分析和理解题目的要求,通过推理、设计和数学推导等方法,构造出满足条件和要求的解。
通过多次练习和不断的思考,我们可以提高自己在ACM竞赛中解决构造题的能力。
github acm竞赛模板 -回复
github acm竞赛模板-回复什么是ACM竞赛模板?解答:ACM竞赛模板是一种常用的编程竞赛工具,主要用于帮助参赛选手快速编写算法和代码。
ACM竞赛模板包含了常见的数据结构、算法和代码片段,方便选手在比赛中快速实现题目要求。
一步一步回答:1. ACME竞赛模板是什么?ACM竞赛模板是一个综合性的编程工具包,针对ACM(Association for Computing Machinery)计算机竞赛而设计。
它包含了常见的数据结构(如栈、队列、链表、堆等)和常用的算法(如排序、查找、递归等),旨在帮助参赛选手快速编写高效的代码解决问题。
2. ACM竞赛模板有哪些特点?ACM竞赛模板的特点主要有以下几个方面:- 综合性:ACM竞赛模板包含了各种常用的数据结构和算法,如树、图、并查集、动态规划等。
选手可以根据题目要求选择适当的数据结构和算法进行实现。
- 高效性:ACM竞赛模板中的算法和代码片段经过优化,具有较高的执行效率。
这对于竞赛中的时间限制非常重要。
- 易用性:ACM竞赛模板的代码清晰、简洁,采用了规范的命名和注释,方便选手理解和使用。
- 可扩展性:ACM竞赛模板是一个基础框架,选手可以根据具体需求进行扩展和修改,以适应不同的竞赛题目。
3. ACM竞赛模板如何使用?使用ACM竞赛模板可以遵循以下步骤:- 下载模板:从GitHub或其他代码库中下载ACM竞赛模板的代码文件。
- 配置环境:根据模板的要求配置编程环境,例如C++或Java的编译器。
- 阅读文档:阅读ACM竞赛模板的说明文档,了解各个函数和数据结构的使用方法和参数说明。
- 编写代码:根据题目要求,在模板的基础上编写相应的算法和代码,实现题目要求。
可以根据需要引入模板中的各个函数和数据结构。
- 调试测试:对编写的代码进行调试和测试,确保功能正确性。
可以使用示例输入数据和预期输出进行测试。
- 提交代码:将编写的代码提交到竞赛平台或评审者处,等待评测结果。
计算流体CFD2004-5
椭圆一抛物 椭圆一双曲
单一类型方程组——平衡型(椭圆型)或发展型(双曲、 抛物型)比较容易处理,分别为纯边值、初边值问题
椭圆型与双曲或抛物型混合的方程组处理起来很困难,必须在 数学上进行讨论与分析。(定解条件提法,论述求解方法、分析 求解时应注意的问题。)
华中科技大学能源与动力工程学院
不可压定常N-S方程是椭圆型方程,其他不可压情
况都是混合型方程。动量方程中有压力项,使压强信 息瞬间传遍全域,不能按时间推进求解
在不可压缩流场的控制方程的动量方程中,压力梯
度是以源项形式出现,压力没有独立的方程(在可压缩流 体中压力与密度问的关系由状态方程所规定)。在以速度、压 力为求解变量的原始变量法中,为了解决压力没有独 立的方程的困难,先后发展了 ●人工压缩性方法 ●压力修正算法(pressure—correction method)等方法。 其中以压力修正算法——如SIMPLE系列的应用最广 。 ● κ-ω方法不是原始变量法,它避开了压力项。
引入û , v后,动量离散方程式便可写为
华中科技大学能源与动力工程学院
(2)据û , v计算相应的压力场p*。 将动量离散式代入质量守恒方程的离散形式求解, (其中anb,ap及b的计算式形式上与SIMPLE算法中的p’ 方程的一样,只要将û , v代替ū, 即可)
(3)求解动量离散方程,得ū,。 v
以上四条是其后所出现的一些改进方案的着眼之处。
华中科技大学能源与动力工程学院
2、SIMPLER
SIMPLER(1980)算法主要用以改进SIMPLE方法中 的第一项近似处理方法。一旦速度场给定,压力场就 可以从动量离散方程中予以求解,而不再任意假定。 其主要计算步骤如下:
ACM大牛总结的线段树专辑,超经典的
【完全版】线段树很早前写的那篇线段树专辑至今一直是本博客阅读点击量最大的一片文章,当时觉得挺自豪的,还去pku打广告,但是现在我自己都不太好意思去看那篇文章了,觉得当时的代码风格实在是太丑了,很多线段树的初学者可能就是看着这篇文章来练习的,如果不小心被我培养出了这么糟糕的风格,实在是过意不去,正好过几天又要给集训队讲解线段树,所以决定把这些题目重新写一遍,顺便把近年我接触到的一些新题更新上去~;并且学习了splay等更高级的数据结构后对线段树的体会有更深了一层,线段树的写法也就比以前飘逸,简洁且方便多了.在代码前先介绍一些我的线段树风格:∙maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍∙lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示∙以前的写法是另外开两个个数组记录每个结点所表示的区间,其实这个区间不必保存,一边算一边传下去就行,只需要写函数的时候多两个参数,结合lson和rson的预定义可以很方便∙PushUP(int rt)是把当前结点的信息更新到父结点∙PushDown(int rt)是把当前结点的信息更新给儿子结点∙rt表示当前子树的根(root),也就是当前所在的结点整理这些题目后我觉得线段树的题目整体上可以分成以下四个部分:∙单点更新:最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来o hdu1166 敌兵布阵题意:O(-1)思路:O(-1)线段树功能:update:单点增减query:区间求和?View Code CPP1 2 3 4 5 6 7 8 910111213 #include <cstdio>#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =55555;int sum[maxn<<2];void PushUP(int rt){sum[rt]= sum[rt<<1]+ sum[rt<<1|1]; }void build(int l,int r,int rt){if(l == r){scanf("%d",&sum[rt]);return;1415161718192021222324252627282930313233343536373839404142434445464748495051525354555657}int m =(l + r)>>1;build(lson);build(rson);PushUP(rt);}void update(int p,int add,int l,int r,int rt){if(l == r){sum[rt]+= add;return;}int m =(l + r)>>1;if(p <= m) update(p , add , lson);else update(p , add , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt){if(L <= l && r <= R){return sum[rt];}int m =(l + r)>>1;int ret =0;if(L <= m) ret += query(L , R , lson);if(R > m) ret += query(L , R , rson);return ret;}int main(){int T , n;scanf("%d",&T);for(int cas =1; cas <= T ; cas ++){printf("Case %d:\n",cas);scanf("%d",&n);build(1 , n , 1);char op[10];while(scanf("%s",op)){if(op[0]=='E')break;int a , b;scanf("%d%d",&a,&b);if(op[0]=='Q')printf("%d\n",query(a , b , 1 , n , 1));elseif(op[0]=='S') update(a , -b , 1 , n , 1);else update(a , b , 1 , n , 1);}}return0;58 }o hdu1754 I Hate It题意:O(-1)思路:O(-1)线段树功能:update:单点替换query:区间最值?View Code CPP1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738 #include <cstdio>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =222222;int MAX[maxn<<2];void PushUP(int rt){MAX[rt]= max(MAX[rt<<1] , MAX[rt<<1|1]);}void build(int l,int r,int rt){if(l == r){scanf("%d",&MAX[rt]);return;}int m =(l + r)>>1;build(lson);build(rson);PushUP(rt);}void update(int p,int sc,int l,int r,int rt){if(l == r){MAX[rt]= sc;return;}int m =(l + r)>>1;if(p <= m) update(p , sc , lson);else update(p , sc , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt){if(L <= l && r <= R){return MAX[rt];}int m =(l + r)>>1;int ret =0;if(L <= m) ret = max(ret , query(L , R , lson));3940414243444546474849505152535455if(R > m) ret = max(ret , query(L , R , rson));return ret;}int main(){int n , m;while(~scanf("%d%d",&n,&m)){build(1 , n , 1);while(m --){char op[2];int a , b;scanf("%s%d%d",op,&a,&b);if(op[0]=='Q')printf("%d\n",query(a , b , 1 , n , 1));else update(a , b , 1 , n , 1);}}return0;}o hdu1394 Minimum Inversion Number题意:求Inversion后的最小逆序数思路:用O(nlogn)复杂度求出最初逆序数后,就可以用O(1)的复杂度分别递推出其他解线段树功能:update:单点增减query:区间求和?View Code CPP1 2 3 4 5 6 7 8 9101112131415161718192021 #include <cstdio>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =5555;int sum[maxn<<2];void PushUP(int rt){sum[rt]= sum[rt<<1]+ sum[rt<<1|1]; }void build(int l,int r,int rt){sum[rt]=0;if(l == r)return;int m =(l + r)>>1;build(lson);build(rson);}void update(int p,int l,int r,int rt){if(l == r){sum[rt]++;22232425262728293031323334353637383940414243444546474849505152535455565758return;}int m =(l + r)>>1;if(p <= m) update(p , lson);else update(p , rson);PushUP(rt);}int query(int L,int R,int l,int r,int rt){if(L <= l && r <= R){return sum[rt];}int m =(l + r)>>1;int ret =0;if(L <= m) ret += query(L , R , lson);if(R > m) ret += query(L , R , rson);return ret;}int x[maxn];int main(){int n;while(~scanf("%d",&n)){build(0 , n -1 , 1);int sum =0;for(int i =0; i < n ; i ++){scanf("%d",&x[i]);sum += query(x[i] , n -1 , 0 , n -1 , 1);update(x[i] , 0 , n -1 , 1);}int ret = sum;for(int i =0; i < n ; i ++){sum += n - x[i]- x[i]-1;ret = min(ret , sum);}printf("%d\n",ret);}return0;}o hdu2795 Billboard题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子思路:每次找到最大值的位子,然后减去L线段树功能:query:区间求最大值的位子(直接把update的操作在query里做了) ?View Code CPP1 2 #include <cstdio>#include <algorithm>3 4 5 6 7 8 910 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 usingnamespace std ;#define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 constint maxn =222222; int h , w , n ; int MAX [maxn <<2]; void PushUP (int rt ){ MAX [rt ]= max (MAX [rt <<1] , MAX [rt <<1|1]);}void build (int l,int r,int rt ){ MAX [rt ]= w ; if (l == r )return ; int m =(l + r )>>1; build (lson ); build (rson );}int query (int x,int l,int r,int rt ){ if (l == r ){ MAX [rt ]-= x ; return l ;}int m =(l + r )>>1;int ret =(MAX [rt <<1]>= x )? query (x , lson ): query (x , rson ); PushUP (rt ); return ret ;}int main (){ while (~scanf ("%d%d%d",&h,&w,&n )){ if (h > n ) h = n ; build (1 , h , 1); while (n --){ int x ;scanf ("%d",&x ); if (MAX [1]< x )puts ("-1");else printf ("%d \n ",query (x , 1 , h , 1));}} return 0;}练习:成段更新(通常这对初学者来说是一道坎),需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候o hdu1698 Just a Hook题意:O(-1)思路:O(-1)线段树功能:update:成段替换(由于只query一次总区间,所以可以直接输出1结点的信息)?View Code CPP1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435 #include <cstdio>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =111111;int h , w , n;int col[maxn<<2];int sum[maxn<<2];void PushUp(int rt){sum[rt]= sum[rt<<1]+ sum[rt<<1|1];}void PushDown(int rt,int m){if(col[rt]){col[rt<<1]= col[rt<<1|1]= col[rt];sum[rt<<1]=(m -(m >>1))* col[rt];sum[rt<<1|1]=(m >>1)* col[rt];col[rt]=0;}}void build(int l,int r,int rt){col[rt]=0;sum[rt]=1;if(l == r)return;int m =(l + r)>>1;build(lson);build(rson);PushUp(rt);}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){col[rt]= c;sum[rt]= c *(r - l +1);return;36373839404142434445464748495051525354555657}PushDown(rt , r - l +1);int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(R > m) update(L , R , c , rson);PushUp(rt);}int main(){int T , n , m;scanf("%d",&T);for(int cas =1; cas <= T ; cas ++){scanf("%d%d",&n,&m);build(1 , n , 1);while(m --){int a , b , c;scanf("%d%d%d",&a,&b,&c);update(a , b , c , 1 , n , 1);}printf("Case %d: The total value of the hook is %d.\n",cas , sum[1]);}return0;}o poj3468 A Simple Problem with Integers 题意:O(-1)思路:O(-1)线段树功能:update:成段增减query:区间求和?View Code CPP1 2 3 4 5 6 7 8 91011121314151617 #include <cstdio>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1#define LL long longconstint maxn =111111;LL add[maxn<<2];LL sum[maxn<<2];void PushUp(int rt){sum[rt]= sum[rt<<1]+ sum[rt<<1|1]; }void PushDown(int rt,int m){if(add[rt]){add[rt<<1]+= add[rt];add[rt<<1|1]+= add[rt];1819202122232425262728293031323334353637383940414243444546474849505152535455565758596061sum[rt<<1]+= add[rt]*(m -(m >>1));sum[rt<<1|1]+= add[rt]*(m >>1);add[rt]=0;}}void build(int l,int r,int rt){add[rt]=0;if(l == r){scanf("%lld",&sum[rt]);return;}int m =(l + r)>>1;build(lson);build(rson);PushUp(rt);}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){add[rt]+= c;sum[rt]+=(LL)c *(r - l +1);return;}PushDown(rt , r - l +1);int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(m < R) update(L , R , c , rson);PushUp(rt);}LL query(int L,int R,int l,int r,int rt){if(L <= l && r <= R){return sum[rt];}PushDown(rt , r - l +1);int m =(l + r)>>1;LL ret =0;if(L <= m) ret += query(L , R , lson);if(m < R) ret += query(L , R , rson);return ret;}int main(){int N , Q;scanf("%d%d",&N,&Q);build(1 , N , 1);while(Q --){62636465666768697071727374char op[2];int a , b , c;scanf("%s",op);if(op[0]=='Q'){scanf("%d%d",&a,&b);printf("%lld\n",query(a , b , 1 , N , 1));}else{scanf("%d%d%d",&a,&b,&c);update(a , b , c , 1 , N , 1);}}return0;}o poj2528 Mayor’s posters题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报思路:这题数据范围很大,直接搞超时+超内存,需要离散化:离散化简单的来说就是只取我们需要的值来用,比如说区间[1000,2000],[1990,2012] 我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要1000,1990,2000,2012就够了,将其分别映射到0,1,2,3,在于复杂度就大大的降下来了所以离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多而这题的难点在于每个数字其实表示的是一个单位长度(并且一个点),这样普通的离散化会造成许多错误(包括我以前的代码,poj这题数据奇弱)给出下面两个简单的例子应该能体现普通离散化的缺陷:1-10 1-4 5-101-10 1-4 6-10为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.线段树功能:update:成段替换query:简单hash?View Code CPP1 2 3 4 5 6 7 8 9101112 #include <cstdio>#include <cstring>#include <algorithm> usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =11111;bool hash[maxn];int li[maxn] , ri[maxn];int X[maxn*3];int col[maxn<<4];1314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 int cnt;void PushDown(int rt){if(col[rt]!=-1){col[rt<<1]= col[rt<<1|1]= col[rt];col[rt]=-1;}}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){col[rt]= c;return;}PushDown(rt);int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(m < R) update(L , R , c , rson);}void query(int l,int r,int rt){if(col[rt]!=-1){if(!hash[col[rt]]) cnt ++;hash[ col[rt]]=true;return;}if(l == r)return;int m =(l + r)>>1;query(lson);query(rson);}int Bin(int key,int n,int X[]){int l =0 , r = n -1;while(l <= r){int m =(l + r)>>1;if(X[m]== key)return m;if(X[m]< key) l = m +1;else r = m -1;}return-1;}int main(){int T , n;scanf("%d",&T);while(T --){scanf("%d",&n);57585960616263646566676869707172737475767778798081828384int nn =0;for(int i =0; i < n ; i ++){scanf("%d%d",&li[i] , &ri[i]);X[nn++]= li[i];X[nn++]= ri[i];}sort(X , X + nn);int m =1;for(int i =1; i < nn; i ++){if(X[i]!= X[i-1]) X[m ++]= X[i];}for(int i = m -1; i >0; i --){if(X[i]!= X[i-1]+1) X[m ++]= X[i-1]+1;}sort(X , X + m);memset(col , -1 , sizeof(col));for(int i =0; i < n ; i ++){int l = Bin(li[i] , m , X);int r = Bin(ri[i] , m , X);update(l , r , i , 0 , m , 1);}cnt =0;memset(hash , false , sizeof(hash));query(0 , m , 1);printf("%d\n",cnt);}return0;}o poj3225 Help with Intervals题意:区间操作,交,并,补等思路:我们一个一个操作来分析:(用0和1表示是否包含区间,-1表示该区间内既有包含又有不包含)U:把区间[l,r]覆盖成1I:把[-∞,l)(r,∞]覆盖成0D:把区间[l,r]覆盖成0C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换S:[l,r]区间0/1互换成段覆盖的操作很简单,比较特殊的就是区间0/1互换这个操作,我们可以称之为异或操作很明显我们可以知道这个性质:当一个区间被覆盖后,不管之前有没有异或标记都没有意义了所以当一个节点得到覆盖标记时把异或标记清空而当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记开区间闭区间只要数字乘以2就可以处理(偶数表示端点,奇数表示两端点间的区间)线段树功能:update:成段替换,区间异或query:简单hash?View Code CPP1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 #include <cstdio>#include <cstring>#include <cctype>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =131072;bool hash[maxn];int cover[maxn<<2];int XOR[maxn<<2];void FXOR(int rt){if(cover[rt]!=-1) cover[rt]^=1;else XOR[rt]^=1;}void PushDown(int rt){if(cover[rt]!=-1){cover[rt<<1]= cover[rt<<1|1]= cover[rt];XOR[rt<<1]= XOR[rt<<1|1]=0;cover[rt]=-1;}if(XOR[rt]){FXOR(rt<<1);FXOR(rt<<1|1);XOR[rt]=0;}}void update(char op,int L,int R,int l,int r,int rt){if(L <= l && r <= R){if(op =='U'){cover[rt]=1;XOR[rt]=0;}elseif(op =='D'){cover[rt]=0;XOR[rt]=0;}elseif(op =='C'|| op =='S'){FXOR(rt);}4041424344454647484950515253545556575859606162636465666768697071727374757677787980818283return;}PushDown(rt);int m =(l + r)>>1;if(L <= m) update(op , L , R , lson);elseif(op =='I'|| op =='C'){XOR[rt<<1]= cover[rt<<1]=0;}if(m < R) update(op , L , R , rson);elseif(op =='I'|| op =='C'){XOR[rt<<1|1]= cover[rt<<1|1]=0;}}void query(int l,int r,int rt){if(cover[rt]==1){for(int it = l ; it <= r ; it ++){hash[it]=true;}return;}elseif(cover[rt]==0)return;if(l == r)return;PushDown(rt);int m =(l + r)>>1;query(lson);query(rson);}int main(){cover[1]= XOR[1]=0;char op , l , r;int a , b;while( ~scanf("%c %c%d,%d%c\n",&op , &l , &a , &b , &r)){a <<=1 ,b <<=1;if(l =='(') a ++;if(r ==')') b --;if(a > b){if(op =='C'|| op =='I'){cover[1]= XOR[1]=0;}}else update(op , a , b , 0 , maxn , 1);}query(0 , maxn , 1);bool flag =false;int s =-1 , e;for(int i =0; i <= maxn ; i ++){84858687888990919293949596979899if(hash[i]){if(s ==-1) s = i;e = i;}else{if(s !=-1){if(flag)printf(" ");flag =true;printf("%c%d,%d%c",s&1?'(':'[' , s>>1 , (e+1)>>1 , e&1?')':']');s =-1;}}}if(!flag)printf("empty set");puts("");return0;}∙练习:o poj1436 Horizontally Visible Segmentso poj2991 Craneo Another LCISo Bracket Sequence∙区间合并这类题目会询问区间中满足条件的连续最长区间,所以PushUp的时候需要对左右儿子的区间进行合并o poj3667 Hotel题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边2 a b:将[a,a+b-1]的房间清空思路:记录区间中最长的空房间线段树操作:update:区间替换query:询问满足条件的最左断点?View Code CPP1 2 3 4 5 6 7 8 9101112 #include <cstdio>#include <cstring>#include <cctype>#include <algorithm>usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =55555;int lsum[maxn<<2] , rsum[maxn<<2] , msum[maxn<<2]; int cover[maxn<<2];1314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 void PushDown(int rt,int m){if(cover[rt]!=-1){cover[rt<<1]= cover[rt<<1|1]= cover[rt];msum[rt<<1]= lsum[rt<<1]= rsum[rt<<1]= cover[rt]?0: m -(m >>1);msum[rt<<1|1]= lsum[rt<<1|1]= rsum[rt<<1|1]=cover[rt]?0:(m >>1);cover[rt]=-1;}}void PushUp(int rt,int m){lsum[rt]= lsum[rt<<1];rsum[rt]= rsum[rt<<1|1];if(lsum[rt]== m -(m >>1)) lsum[rt]+= lsum[rt<<1|1];if(rsum[rt]==(m >>1)) rsum[rt]+= rsum[rt<<1];msum[rt]= max(lsum[rt<<1|1]+ rsum[rt<<1] , max(msum[rt<<1] , msum[rt<<1|1]));}void build(int l,int r,int rt){msum[rt]= lsum[rt]= rsum[rt]= r - l +1;cover[rt]=-1;if(l == r)return;int m =(l + r)>>1;build(lson);build(rson);}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){msum[rt]= lsum[rt]= rsum[rt]= c ?0: r - l +1;cover[rt]= c;return;}PushDown(rt , r - l +1);int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(m < R) update(L , R , c , rson);PushUp(rt , r - l +1);}int query(int w,int l,int r,int rt){if(l == r)return l;PushDown(rt , r - l +1);int m =(l + r)>>1;if(msum[rt<<1]>= w)return query(w , lson);elseif(rsum[rt<<1]+ lsum[rt<<1|1]>= w)return m - rsum[rt<<1]+1;57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 return query (w , rson );}int main (){ int n , m ;scanf ("%d%d",&n,&m ); build (1 , n , 1); while (m --){ int op , a , b ; scanf ("%d",&op ); if (op ==1){ scanf ("%d",&a ); if (msum [1]< a )puts ("0"); else { int p = query (a , 1 , n , 1); printf ("%d \n ",p );update (p , p + a -1 , 1 , 1 , n , 1);}}else { scanf ("%d%d",&a,&b );update (a , a + b -1 , 0 , 1 , n , 1);}} return 0;}∙ 练习:5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748 usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1constint maxn =2222;int cnt[maxn <<2];double sum[maxn <<2];double X[maxn];struct Seg {double h , l , r;int s;Seg(){}Seg(double a,double b,double c,int d): l(a) , r(b) , h(c) , s(d){}bool operator <(const Seg &cmp)const{return h < cmp.h;}}ss[maxn];void PushUp(int rt,int l,int r){if(cnt[rt]) sum[rt]= X[r+1]- X[l];elseif(l == r) sum[rt]=0;else sum[rt]= sum[rt<<1]+ sum[rt<<1|1];}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){cnt[rt]+= c;PushUp(rt , l , r);return;}int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(m < R) update(L , R , c , rson);PushUp(rt , l , r);}int Bin(double key,int n,double X[]){int l =0 , r = n -1;while(l <= r){int m =(l + r)>>1;if(X[m]== key)return m;if(X[m]< key) l = m +1;else r = m -1;}return-1;}int main(){495051525354555657585960616263646566676869707172737475767778int n , cas =1;while(~scanf("%d",&n)&& n){int m =0;while(n --){double a , b , c , d;scanf("%lf%lf%lf%lf",&a,&b,&c,&d);X[m]= a;ss[m++]= Seg(a , c , b , 1);X[m]= c;ss[m++]= Seg(a , c , d , -1);}sort(X , X + m);sort(ss , ss + m);int k =1;for(int i =1; i < m ; i ++){if(X[i]!= X[i-1]) X[k++]= X[i];}memset(cnt , 0 , sizeof(cnt));memset(sum , 0 , sizeof(sum));double ret =0;for(int i =0; i < m -1; i ++){int l = Bin(ss[i].l , k , X);int r = Bin(ss[i].r , k , X)-1;if(l <= r) update(l , r , ss[i].s , 0 , k -1, 1);ret += sum[1]*(ss[i+1].h- ss[i].h);}printf("Test case #%d\n Total explored area: %.2lf\n\n",cas++, ret);}return0;}o hdu1828 Picture题意:矩形周长并思路:与面积不同的地方是还要记录竖的边有几个(numseg记录),并且当边界重合的时候需要合并(用lbd和rbd表示边界来辅助)线段树操作:update:区间增减query:直接取根节点的值?View Code CPP1 2 3 4 5 6 7 8 #include <cstdio>#include <cstring>#include <cctype>#include <algorithm> usingnamespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 constint maxn =22222;struct Seg{int l , r , h , s;Seg(){}Seg(int a,int b,int c,int d):l(a) , r(b) , h(c) , s(d){}bool operator <(const Seg &cmp)const{if(h == cmp.h)return s > cmp.s;return h < cmp.h;}}ss[maxn];bool lbd[maxn<<2] , rbd[maxn<<2];int numseg[maxn<<2];int cnt[maxn<<2];int len[maxn<<2];void PushUP(int rt,int l,int r){if(cnt[rt]){lbd[rt]= rbd[rt]=1;len[rt]= r - l +1;numseg[rt]=2;}elseif(l == r){len[rt]= numseg[rt]= lbd[rt]= rbd[rt]=0;}else{lbd[rt]= lbd[rt<<1];rbd[rt]= rbd[rt<<1|1];len[rt]= len[rt<<1]+ len[rt<<1|1];numseg[rt]= numseg[rt<<1]+ numseg[rt<<1|1];if(lbd[rt<<1|1]&& rbd[rt<<1]) numseg[rt]-=2;//两条线重合}}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){cnt[rt]+= c;PushUP(rt , l , r);return;}int m =(l + r)>>1;if(L <= m) update(L , R , c , lson);if(m < R) update(L , R , c , rson);PushUP(rt , l , r);}int main(){int n;while(~scanf("%d",&n)){int m =0;53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 6970 71 72 73int lbd =10000, rbd =-10000;for (int i =0; i < n ; i ++){int a , b , c , d ;scanf ("%d%d%d%d",&a,&b,&c,&d );lbd = min (lbd , a );rbd = max (rbd , c );ss [m ++]= Seg (a , c , b , 1);ss [m ++]= Seg (a , c , d , -1);}sort (ss , ss + m );int ret =0 , last =0;for (int i =0; i < m ; i ++){if (ss [i ].l < ss [i ].r ) update (ss [i ].l , ss [i ].r -1 , ss [i ].s , lbd , rbd -1 , 1);ret += numseg [1]*(ss [i +1].h - ss [i ].h );ret +=abs (len [1]- last );last = len [1];}printf ("%d \n ",ret );}return 0; } ∙ 练习。
simple 算法、simplec 算法和 piso 算法
simple 算法、simplec 算法和 piso 算法简单算法是指实现相对简单的算法,通常是由少量的步骤组成,适用于解决基础性问题。
简单算法的特点是易于理解和实现,但可能在处理复杂问题时效率较低。
下面将介绍几种常见的简单算法:顺序查找、冒泡排序和线性插值搜索。
顺序查找(Sequential Search)是一种简单的搜索算法,它逐一比较列表中的元素,直到找到匹配的元素或遍历完整个列表。
这个算法的时间复杂度为O(n),其中n为列表的长度。
顺序查找适用于小型列表或未排序列表,但在大型数据集上,效率较低。
它的伪代码如下:```function sequentialSearch(list, target):for i from 0 to length(list) - 1 doif list[i] is equal to target thenreturn ireturn -1```冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地比较相邻的两个元素,并交换它们直到整个列表排序完成。
冒泡排序的时间复杂度为O(n^2),其中n为列表的长度。
尽管冒泡排序的效率较低,但它实现简单,适用于小型数据集或基础排序需求。
它的伪代码如下:```function bubbleSort(list):for i from 0 to length(list) - 1 dofor j from 0 to length(list) - i - 1 doif list[j] > list[j+1] thenswap(list[j], list[j+1])```线性插值搜索(Linear Interpolation Search)是一种简单的搜索算法,用于在有序列表中寻找目标元素。
它利用目标元素与列表范围的线性关系进行搜索,从而提高搜索效率。
线性插值搜索的时间复杂度为O(log(log(n))),其中n为列表的长度。
SIMPLE算法介绍
SIMPLE算法介绍简单算法指的是解决问题的一种基础算法,它通常具有简单直观、易于理解和实现的特点。
本文将介绍几个常见的简单算法,包括递归算法、排序算法、算法和贪心算法。
一、递归算法递归算法是指一个函数调用自身的过程。
它将一个大型的问题拆分为一个或多个与原问题类似但规模较小的子问题,并通过递归调用解决这些子问题,最后组合子问题的结果来解决原问题。
递归算法通常有两个部分:基线条件和递归条件。
基线条件指的是递归停止的条件,递归条件指的是问题拆分为子问题的条件。
例如,计算阶乘的算法可以使用递归实现:```pythondef factorial(n):if n == 1:return 1else:return n * factorial(n-1)```递归算法可以解决一些复杂的问题,但是由于递归调用本身的开销较大,可能会导致性能问题和栈溢出等问题。
二、排序算法排序算法的目标是将一组数据按照一些规则进行排序。
常见的排序算法有冒泡排序、插入排序、选择排序、快速排序、归并排序等。
冒泡排序的思想是依次比较相邻的元素,如果顺序不对则交换它们的位置,直到全部元素都按照规则排序。
插入排序的思想是将每个元素插入到已经排好序的子序列中的适当位置。
选择排序的思想是每次选择最小的元素放到已经排好序的子序列的末尾。
快速排序的思想是选取一个基准值,将小于基准值的元素都放到基准值的左边,大于基准值的元素都放到基准值的右边,然后对左右两个子序列递归地进行快速排序。
归并排序的思想是将序列拆分成两个子序列,对两个子序列分别进行排序,然后将两个排好序的子序列合并成一个有序序列。
三、算法算法是指在给定的数据集中查找一些特定元素或满足其中一种条件的元素。
常见的算法有顺序、二分、深度优先和广度优先等。
顺序是逐个比较数据集中的元素,直到找到目标元素或遍历完整个数据集。
二分是在已经排好序的数据集中逐步缩小范围。
首先将数据集分成两半,然后判断目标元素在哪一半中,再递归地对目标半部分进行二分。
acm模式的javascript链表题
ACM 模式的 JavaScript 链表题随着互联网技术的迅速发展,编程竞赛已经成为程序员在提高自己能力的重要方式,而 ACM(大学生程序设计竞赛)模式的题目也成为了程序员们考察自己水平的常见方式。
在 ACM 题目中,链表题目是常见的一类,需要灵活运用数据结构和算法知识来解决问题。
本文将结合 JavaScript 语言,从链表的基本操作、链表的常见问题、以及解决链表问题的常用技巧等方面来讨论 ACM 模式的 JavaScript 链表题。
一、链表的基本操作链表是一种常见的数据结构,它由一系列节点组成,每个节点包含了一个数据元素和一个指向下一个节点的指针。
在 JavaScript 中,链表可以通过对象的引用来实现。
下面是一个简单的 JavaScript 链表的实现示例:```javascriptclass ListNode {constructor(val, next = null) {this.val = val;this.next = next;}}```在这个示例中,我们定义了一个 ListNode 类来表示链表的节点,每个节点包含一个 val 属性用来存储值,以及一个 next 属性用来指向下一个节点。
通过这样的方式,我们就可以创建一个简单的链表:```javascriptlet node1 = new ListNode(1);let node2 = new ListNode(2);let node3 = new ListNode(3);node1.next = node2;node2.next = node3;```通过以上链表的基本操作,我们可以实现链表的创建和遍历等功能。
二、链表的常见问题在ACM 模式的题目中,链表问题通常涉及到链表的增删改查等操作,常见的问题包括反转链表、合并两个有序链表、删除链表的倒数第 N 个节点等。
下面我们来逐一讨论这些问题的解决方法:1. 反转链表反转链表是一个常见的问题,可以通过迭代或递归的方式来解决。
(lecture_01)初识ACM_20070925_simple ACM课件
Run Time Error -- 程序运行过程中出现非正常中断。
Time Limit Exceeded
-- 运行超过时限还没有得到输出结果。
Wrong Answer -- 答案错误。
Presentation Error
-- 输出格式不对,可检查空格、回车等等细节。
Accepted -- 恭喜恭喜!
26 2020/9/29
Hdoj_1089源代码:
#include <stdio.h> int main() {
int a,b;
while(scanf("%d %d",&a, &b) != EOF) printf("%d\n",a+b);
}
27 2020/9/29
本类输入解决方案:
C语法: while(scanf("%d %d",&a, &b) != EOF) { .... }
2006年5月,浙江省第二届“舜宇”杯大学生程序设计大 赛
2006年11~12月,第31届ACM首尔、北京、上海和西安赛 区比赛
今年…
9 2020/9/29
预期赛事(今后每年)
3~4月,举行校内大赛(暨选拔赛) 5月,参加浙江省大学生程序设计大赛 11月,参加ACM/ICPC亚洲区比赛(至
38 2020/9/29
说明(5_1):
scanf(“ %s%s”,str1,str2),在多个字符串 之间用一个或多个空格分隔;
若使用gets函数,应为gets(str1); gets(str2); 字符串之间用回车符作分隔。
通常情况下,接受短字符用scanf函数, 接受长字符用gets函数。
MWC飞控
CRIUS MWC MultiWii SE v2.5 飞控板MWC是不带任何说明书和操作指南,可以自己登陆官网查看,以下为官网网址:SE v2.5 硬件特点1 优化布局,信号输入/输出接口位置更合理;2 更换性能更好的陀螺/加速度一体化6轴传感器;2 使用专用I2C电平转换IC;2 具有FTDI保护设计,防止外部供电与USB供电冲突;3 带有I2C(5V电平)接口,可连接I2C-GPS导航板/OLED显示屏等外围设备;4 尺寸紧凑,可装在迷你机架上,也可通过CRIUS分电板转换成“标准”45mm安装孔距。
MWC固件简介MWC是MultiWii Copter的缩写,它并不是指硬件产品,而是开源固件。
此固件的原创作者是来自法国的Alex,他为了打造自己的Y3飞行器而开发了最初的MWC固件(原创交流帖与官网的链接在最下方)。
几年来经过许多高手的参与及共同努力,开发进度越来越快。
现在MWC 已经基本成熟,可以支持更广泛的硬件平台、外围设备及更多飞行模式,让运行MWC的飞控硬件成为国外开源飞控市场上占有率最高之一的产品。
MWC固件支持的硬件平台MWC固件是用Arduino IDE来编写,支持Arduino发布的几种主要的AVR开发板Pro Mini/Pro Micro/Mega等,也可支持使用STM32的Arduino兼容平台,但STM32目前无法体现出任何性能与端口上的优势,所以仍以AVR为主流,成熟、够用且稳定。
本产品CRIUS MultiWii Standard Edition(SE) v2.0是基于Arduino Pro Mini来设计,使用ATmega328P单片机。
MWC固件支持的外围设备1 蓝牙调参模块- 用安卓手机/平板电脑来调试参数(推荐使用)2 OLED显示屏模块- 可作为机载状态/参数显示器,也可搭配遥控器进行参数调试(不建议使用)3 I2C-GPS导航板- 328P飞控可通过它连接GPS,用于定点/自动返航以及航点飞行功能4 GPS - 用于定点/自动返航5 OSD - FPV必备,可显示飞控与GPS数据6 数传模块- APC2XX/Xbee/3DR Radio等,用于遥测功能7 光流模块- 用于定点飞行8 声纳模块- 用于低空高精度定高飞行CRIUS的2款飞控,运行MWC时所支持的设备对比AIOP:1/2/4/5/6/7/8SE:1/2/3/4/5/6/8MWC固件支持的飞行器模式下载最新的固件可支持以下飞行器模式,可自由在源代码中选择所需的模式并上传到飞控。
ACM算法分类汇总
ACM算法分类汇总
ACM(Advanced Classification Machine Learning)算法是一种使用计算机程序对数据进行分类的方法。
它通过学习已知分类的数据集,然后根据学习到的模型对未知数据进行分类。
ACM算法在许多领域中被广泛应用,如医学诊断、金融风险评估和电子商务推荐系统等。
在监督学习中,常用的ACM算法包括决策树、朴素贝叶斯、支持向量机和神经网络等。
决策树算法使用树形结构表示分类规则,具有可解释性和计算效率高的特点。
朴素贝叶斯算法基于贝叶斯定理,综合考虑各特征对分类的影响。
支持向量机算法通过将样本映射到高维特征空间,在高维空间中找到最优分类超平面。
神经网络算法模拟人脑神经元的工作原理,通过调整神经元之间的连接权重实现分类。
在无监督学习中,常用的ACM算法包括聚类和异常检测等。
聚类算法将数据集划分为若干个类别,使得同一类别内的样本相似度高,不同类别间的相似度低。
常用的聚类算法包括K-Means、DBSCAN和层次聚类等。
异常检测算法用于发现与大多数样本不符的异常样本,常用的异常检测算法包括孤立森林、LOF和聚类离散度等。
总之,ACM算法是一种在数据分类问题中广泛应用的技术。
通过学习已知数据集,利用不同的学习模型对未知数据进行分类。
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。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
重读题 算法问题 程序实现问题 放弃此题
参加ACM-ICPC的一些经验
ACM-ICPC比赛经验-注意细节
细节只能依靠平时积累。
参加ACM-ICPC的一些经验
ACM-ICPC比赛经验-注意细节
二分查找的过程: 用low表示下界,high表示上界 while (low<high) { mid=(low+high)/2; ………….. }
三大高手型——符文杰、张一飞、骆骥 缺点:容易造成各自为政的局面,队员之间过 于信任,交流较少。 当一人在算法上或题意理解上有错误时,不容 易发现问题,并且造成无效用的机器占用。当 比赛末期有若干题可以尝试解决时,难以抵抗 各司一题的诱惑,而实际结果往往是一无所获。
参加ACM-ICPC的一些经验
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
拖后中卫型 拖后中卫型队伍的理想发挥,需要简单题和难 题的数量分布较好。 然而这两年ACM的赛题,往往算法比较容易 想到,但实现有困难,有时要根据数据的情况 做算法优化或特殊处理,因此在很多时候拖后 中卫的实力不一定能得到充分的发挥。
团队合作能力的两个极端 抢键盘 一起敲键盘——Abacus.FDU
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中团队合作的提高
选择最合适的队员和组队模式 Online Contest
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
三大高手型 拖后中卫型 编程高手型
Final Standing 验题赛 Staff->Judger
Asia Beijing2006 Onsite的比赛过程
Asia Beijing 2006 Onsite的验题赛
Robot Animal Run Another Minimum Spanning Tree Connect It, If You Can! Guess XAR What a Special Graph Ruler A Funny Stone Game
ACM-ICPC竞赛中的组队模式
拖后中卫型 有一名队员担当拖后中卫的角色,比赛开始时 另两名队员正常做题,拖后中卫专攻难题。当 简单题差不多做完了,难题也想出算法了,比 赛成绩在解题数和时间上都会有优势。 这种模式保证有充分的时间研究难题,而三大 高手型的队伍,可能一开始每人都做简单题, 机器资源不够,而后来每人都想难题,机器资 源浪费。
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
三大高手型——符文杰、张一飞、骆骥 优点:充分发挥实力,充分利用资源。 一人敲程序时,另两人可以想算法,甚至提前 在纸上写程序框架。一题做毕换人就上,三人 轮流最大限度的使用计算机。
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
编程高手型 一名队员属编程高手,算法基础不错,简单题 完全可独当一面,更重要的是敲程序的速度和 准确度明显强于另两人。
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中的组队模式
编程高手型 这一模式的理想发挥是:程序基本都由编程高 手来敲,另两人负责想算法和把算法告诉高手。 由于高手主攻,所以基本不会造成三大高手型 各司一题的情况。 当面临若干选择时,往往高手可以决定,另两 人也容易接受和配合。由于高手的特点,这样 的队伍在比赛期间解题数量和时间都比较容易 取得优势地位。
IOI和ACM-ICPC的经历
IOI的比赛经历(2001-2002年)
2001年12月:NOIP2001 一等奖 2002年5月:ZJOI2002 第3名 2002年8月:NOI2002 三等奖
IOI和ACM-ICPC的经历
IOI的比赛经历(2002-2004年)
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中个人能力的提高
个人能力的训练时间一般占总时间的: 约40%-99%
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中个人能力的提高
TopCoder
参加ACM-ICPC的一些经验
ACM-ICPC训练经验-TopCoder
/tc SRM,TCO,TCCC
Asia Beijing2006 Onsit Nhomakorabea的比赛过程
Asia Beijing 2006 Onsite的比赛过 程
Staff->Judger Problem A:Robot数据有问题
Asia Beijing2006 Onsite的比赛过程
题目的选择
Robot Animal Run Another Minimum Spanning Tree Connect It, If You Can! Guess XAR What a Special Graph Ruler A Funny Stone Game
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中个人能力的提高 ACM-ICPC竞赛中团队合作能力的培养 ACM-ICPC的竞赛过程
个人能力 vs 团队合作
ACM-ICPC竞赛取得好成绩主要依靠的是两种 能力: 个人能力 团队合作
个人能力 vs 团队合作
ACM-ICPC竞赛取得好成绩主要依靠的是两种 能力: 个人能力:竞赛过程中的每道题目的解决最终 都需要选手的个人能力的支持
参加ACM-ICPC的一些经验
Online Contest
实践是检验真理的唯一标准
参加ACM-ICPC的一些经验
Online Contest
/JudgeOnline acm.uva.es/contest acm.timue.ru acm.sgu.ru ipsc.ksp.sk
队友:贝小辉,张宁 赛区选择: 成都赛区 北京赛区 杭州赛区
IOI和ACM-ICPC的经历
ACM-ICPC(2005-2006)
Asia-Beijing-On Site Contest Asia-Hangzhou-On Site Contest
IOI和ACM-ICPC的经历
ACM-ICPC
Tsinghua University ACRush
ACM-ICPC
自己IOI和ACM-ICPC的经历 参加ACM-ICPC的一些经验 Asia Beijing2006 Onsite的比赛过程
IOI和ACM-ICPC的经历
ACM-ICPC
自己IOI和ACM-ICPC的经历 参加ACM-ICPC的一些经验 Asia Beijing2006 Onsite的比赛过程
IOI和ACM-ICPC的经历
从IOI到ACM-ICPC
自己IOI和ACM-ICPC的经历 参加ACM-ICPC的一些经验 Asia Beijing 2006 Onsite的比赛过程
Asia Beijing2006 Onsite的比赛过程
Asia Beijing 2006 Onsite的比赛过 程
个人能力 vs 团队合作
ACM-ICPC竞赛取得好成绩主要依靠的是两种 能力: 团队合作:比赛过程是3个选手一起协作完成 的。只有好的合作才能有效发挥出每个选手的 特长。
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中个人能力的提高
个人能力一般包括: 思考算法的能力 编程的能力 debug的能力
ACM-ICPC训练经验-TopCoder
TopCoder允许的语言: C++ Java C# VB
参加ACM-ICPC的一些经验
ACM-ICPC训练经验-TopCoder
提高的编程速度 提高的正确率
参加ACM-ICPC的一些经验
ACM-ICPC竞赛中团队合作的提高
参加ACM-ICPC的一些经验
ACM-ICPC的排名方法
首先按照解决题目的数目 其次按照penalty time 再次按照通过最后的时间
参加ACM-ICPC的一些经验
ACM-ICPC比赛经验
比赛规则 Judger的习惯 比赛资料的准备
参加ACM-ICPC的一些经验
ACM-ICPC比赛经验-被卡住之后应对自如
参加ACM-ICPC的一些经验
ACM-ICPC训练经验-TopCoder
TopCoder时间紧凑 TopCoder比赛有丰厚的奖金
参加ACM-ICPC的一些经验
ACM-ICPC训练经验-TopCoder
C++ class STL,vector,string
参加ACM-ICPC的一些经验
2002年11月:NOIP2002 2003年5月:ZJOI2003 2003年8月:NOI2003 2004年1月:WC2004 2004年5月:CTSC2004 2004年8月:IOI2004
一等奖 第1名 一等奖 第1名 第1名 金牌
IOI和ACM-ICPC的经历
ACM-ICPC(2005-2006)
ACM-ICPC(2006-2007)
ACM-ICPC World Final 2007
参加ACM-ICPC的一些经验
ACM-ICPC
自己IOI和ACM-ICPC的经历 参加ACM-ICPC的一些经验 Asia Beijing2006 Onsite的比赛过程