ECNU女队模板

这篇博客主要介绍了ACM竞赛中的常见编程模板,包括STL的使用,如配对、离散化、优先队列、迭代器遍历、next_permutation、Bitset等。此外,还涵盖了输入输出和头文件的处理,Java中处理大整数的方法,树状数组、并查集、数论知识、动态规划、线段树、字符串处理、图论算法、网络流、树结构、矩阵连乘、分治法和解决最近点对问题的思路。
摘要由CSDN通过智能技术生成

Acm模板

walnut, purity, dreamcloud


 

目录

一、         头部... 3

二、         常用STL. 3

配对:... 3

离散化... 4

去重     4

LOWER_BOUND.. 4

离散化(另一种方法,比较低效)... 4

优先队列... 5

迭代器和遍历STL. 5

next_permutation o(n). 5

Bitset. 5

三、输入输出和头文件... 6

四、java高精度and大整数... 8

大整数... 8

高精度... 11

五、树状数组... 21

六、并查集... 23

七、数论... 24

欧拉函数... 24

莫比乌斯函数... 24

欧拉筛... 25

快速幂... 25

乘法逆元... 26

欧几里得算法... 26

八、动态规划... 27

LIS(最长上升子序列)... 27

LCS(最长公共子序列)... 28

最长公共子串... 28

背包问题... 29

九、线段树... 30

模板一... 30

模板二... 31

十、字符串... 33

KMP算法... 33

Trie树... 33

十一、 图论... 35

Floyd. 35

DIJ迪杰斯特拉... 37

最小生成树... 39

十二、网络流... 41

匈牙利算法,最小点覆盖(最大匹配数)二分图匹配... 41

网络流... 42

十三、树... 42

哈夫曼树(二叉搜索树)... 42

十四、矩阵连乘... 45

十五、分治法... 46

最近点对... 46

十六、凸包... 47

十七、解题思路... 50

二分答案+判断(贪心)... 50

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一、头部

1.  #include <bits/stdc++.h>  

2.  /*int类型最大值INT_MAXshort最大值为SHORT_MAX 

3.  long long最大值为LONG_LONG_MAX*/  

4.  #define _clr(x,y) memset(x,y,sizeof(x))  

5.  #define _inf(x) memset(x,0x3f,sizeof(x))  

6.  #define pb push_back  

7.  #define mp make_pair  

8.  #define FORD(i,a,b) for (int i=(a); i<=(b); i++)  

9.  #define FORP(i,a,b) for (int i=(a); i>=(b); i--)  

10. #define REP(i,n) for (int i=0; i<(n); i++)  

11. using namespace std;  

12. const int INF = 0x3f3f3f3f;  

13. const double eps = 1e-8;  

14. const double EULER = 0.577215664901532860;  

15. const double PI = 3.1415926535897932384626;  

16. const double E = 2.71828182845904523536028;  

17.   

18. typedef long long LL;  

 

二、常用STL

配对:

typedef pair<LL,LL>P;

 

离散化的意思是只考虑数值之间的相对大小,节省空间和时间,提高算法效率。

sort(sub_a,sub_a+n);

int size=unique(sub_a,sub_a+n)-sub_a;//size为离散化后元素个数,unique函数去重

for(i=0;i<n;i++)  

a[i]=lower_bound(sub_a,sub_a+size,a[i])-sub_a + 1;

去重

sort(vec.begin(), vec.end());

vec.resize(unique(vec.begin(),vec.end()) - vec.begin());

LOWER_BOUND

lower_bound(sub_a,sub_a+size,a[i]) 返回第一个大于等于a[i]的值的pos

upper_bound(sub_a,sub_a+size,a[i]) 返回第一个大于a[i]的值的pos

 

离散化(另一种方法,比较低效)

1.  LL aa[N];

2.  struct Node  

3.  {  

4.      int v;  

5.      int order;  

6.  }a[N];  

7.  bool cmp(Node a, Node b)  

8.  {  

9.      return a.v < b.v;  

10. }  

11.  

12. int main()

13. {

14.      for (int i = 1; i <= n; i++) {  

15.             scanf("%d", &a[i].v);  

16.             a[i].order = i;  

17.      }  

18.      sort(a + 1, a + n + 1, cmp);  

19.       for (int i = 1; i <= n; i++)  aa[a[i].order] = i;  

20. }

优先队列

1.  priority_queue<int, vector<int>, greater<int> > pq;  

迭代器和遍历STL

1.  map<int,int>::iterator it;  

2.  for(it = mp.begin(); it < mp.end(); it++){  

3.     cout << it.second() << endl;  

4.  }  

5.  int count = vec.size();  

6.  for(int i = 0; i < count; i++){  

7.     cout << vec[i] << endl;  

8.  }  

next_permutation o(n)

1.  void TestArray()     

2.  {    

3.      char chs[] = {'a''d''c''e''b'};    

4.      int count = sizeof(chs)/sizeof(char);    

5.          

6.      next_permutation(chs+0, chs + count);    

7.         

8.      printf("TestArray:\n");    

9.      for(int i = 0; i < count; i++) {    

10.             printf("%c ", chs[i]);    

11.     }    

12.         

13.     printf("\n");    

14. }   

Bitset

见cww模板。

1.  #include <bitset>  

 

 

三、输入输出和头文件

头文件:

1.  #include <iostream>  

2.  #pragma comment(linker, "/STACK:1024000000,1024000000")   

3.  #include <stdio.h>  

4.  #include <fstream>  

5.  #include <iomanip>  

6.  #include <cmath>  

7.  #include <string>  

8.  #include <string.h>  

9.  #include <sstream>  

10. #include <cctype>  

11. #include <climits>  

12. #include <set>  

13. #include <map>  

14. #include <deque>  

15. #include <queue>  

16. #include <vector>  

17. #include <iterator>  

18. #include <algorithm>  

19. #include <stack>  

20. #include <functional>  

21. /*int类型最大值INT_MAXshort最大值为SHORT_MAX 

22. long long最大值为LONG_LONG_MAX*/   

23. #define _clr(x,y) memset(x,y,sizeof(x))  

24. #define _inf(x) memset(x,0x3f,sizeof(x))  

25. #define pb push_back  

26. #define mp make_pair  

27. #define FORD(i,a,b) for (int i=(a); i<=(b); i++)  

28. #define FORP(i,a,b) for (int i=(a); i>=(b); i--)  

29. #define REP(i,n) for (int i=0; i<(n); i++)  

30. using namespace std;  

31. const int INF = 0x3f3f3f3f;  

32. const double eps = 1e-8;  

33. const double EULER = 0.577215664901532860;  

34. const double PI = 3.1415926535897932384626;  

35. const double E = 2.71828182845904523536028;  

36.   

37. typedef long long LL;  

 

文件输入输出:

1.  freopen("a.in","r",stdin);  

2.  freopen("a.out","w",stdout);  

快速读:

1.  struct FastIO    

2.  {    

3.      static const int S = 1310720;    

4.      int wpos;    

5.      char wbuf[S];    

6.      FastIO() : wpos(0) {}    

7.      inline int xchar()    

8.      {    

9.          static char buf[S];    

10.         static int len = 0, pos = 0;    

11.         if (pos == len)    

12.             pos = 0, len = fread(buf, 1, S, stdin);    

13.         if (pos == len) return -1;    

14.         return buf[pos ++];    

15.     }    

16.     inline LL Lint()    

17.     {    

18.         int c = xchar();    

19.         LL x = 0;    

20.         while (c <= 32) c = xchar();    

21.         for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';    

22.         return x;    

23.     }    

24.     inline int xint()    

25.     {    

26.         int s = 1, c = xchar(), x = 0;    

27.         while (c <= 32) c = xchar();    

28.         if (c == '-') s = -1, c = xchar();    

29.         for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';    

30.         return x * s;    

31.     }    

32.     inline void xstring(char *s)    

33.     {    

34.         int c = xchar();    

35.         while (c <= 32) c = xchar();    

36.         for (; c > 32; c = xchar()) * s++ = c;    

37.         *s = 0;    

38.     }    

39.     inline void wchar(int x)    

40.     {    

41.         if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;    

42.         wbuf[wpos ++] = x;    

43.     }    

44.     inline void wint(LL x)    

45.     {    

46.         if (x < 0) wchar('-'), x = -x;    

47.         char s[24];    

48.         int n = 0;    

49.         while (x || !n) s[n ++] = '0' + x % 10, x /= 10;    

50.         while (n--) wchar(s[n]);    

51.     }    

52.     inline void wstring(const char *s)    

53.     {    

54.         while (*s) wchar(*s++);    

55.     }    

56.     ~FastIO()    

57.     {    

58.         if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;    

59.     }    

60. } io;    

61.  n = io.xint(), m = io.xint();    

62.  

cin加速:

1.  std::ios::sync_with_stdio(false);  

 

四、java高精度and大整数

Java.math包中,有BigIntegerBigDecimal两个类,分别可以表示长度不可变的,任意精度的整数和小数,并且可以和字符串相互转换,使得Java在处理大数方面具有独特的优势。

大整数

:在java中的基本头文件(java中叫包)

import java.io.*

importjava.util.*       我们所用的输入scanner在这个包中

importjava.math.*          我们下面要用到的BigInteger就这这个包中

 

二:输入与输出

读入 Scanner cin=new ScannerSystem.in

While(cin.hasNext())   //相当于C语言中的!=EOF

String str =null;

str =cin.next();

n =cin.nextInt();       //输入一个int型整数

n =cin.nextBigInteger();   //输入一个大整数

System.out.print(n);      //输出n但不换行

System.out.println();     //换行

System.out.println(n);    //输出n并换行

System.out.printf(“%d\n”,n);     //类似C语言中的输出

 

三:定义变量

定义单个变量:

int a,b,c;      //C++ 中无区别

BigInteger  a;   //定义大数变量a

BigIntegerb= new BigInteger("2");   //定义大数变量 b赋值为 2

BigDecimaln     //定义大浮点数类 n

定义数组:

int a[]= new int[10 //定义长度为10的数组a

BigInteger  b[] =new BigInteger[100 //定义长度为100的数组a

 

四:表示范围

布尔型 boolean 1 true,falsefalse

字节型byte8 -128-1270

字符型char16 ‘\u000’-\uffff ‘\u0000’

短整型short16 -32768-327670

整型 int 32 -2147483648,21474836470

长整型long64 -9.22E18,9.22E180

浮点型 float 321.4E-45-3.4028E+380.0

双精度型 double 644.9E-324,1.7977E+3080.0

BigInteger任意大的数,原则上只要你的计算机内存足够大,可以有无限位

 

五:常用的一些操作

A=BigInteger.ONE;   //0赋给A

B=BigInteger.valueOf (3);    //3赋给B

A[i]=BigInteger.valueOf (10);    //10赋给A[i]

c=a.add(b)        //ab相加并赋给c

c=a.subtract(b)   //ab相减并赋给c

c=a.multiply(b)   //ab相乘并赋给c

c=a.divide(b)     //ab相除并赋给c

c=a.mod(b)        // 相当于a%b

a.pow(b)          //相当于a^b

a.compareTo(b)      //根据该数值是小于、等于、或大于a 返回 -10 1

a.equals(b)    //判断两数是否相等,也可以用compareTo来代替;

a.min(b)a.max(b) //取两个数的较小、大者;

 

六:例题hdu 5920 求回文数(大整数)

1.  import java.math.*;  

2.  //import java.io.*;  

3.  import java.util.*;  

4.  public class big {  

5.      public static BigInteger fanzhuan(BigInteger n){  

6.          //System.out.println("fanzhuan" + n);  

7.          int k = String.valueOf(n).length();  

8.          BigInteger ret = BigInteger.ZERO;  

9.          for (int i=1;i<=k;i++){  

10.             ret = ret.add(n.mod(BigInteger.TEN));  

11.             ret = ret.multiply(BigInteger.TEN);  

12.             n = n.divide(BigInteger.TEN);  

13.         }  

14.         ret = ret.divide(BigInteger.TEN);  

15.         return ret;  

16.     }  

17.     public static void main(String[] argv){  

18.         Scanner cin = new Scanner(System.in);  

19.         int T =cin.nextInt();  

20.         for (int cas=1;cas<=T;cas++){  

21.             BigInteger n = cin.nextBigInteger();  

22.             int N = String.valueOf(n).length();  

23.             int A = 0;  

24.             BigInteger ans[] = new BigInteger[55];  

25.             for (;N>1;){  

26.                 //System.out.println("n=" + n);  

27.                 BigInteger one0 = BigInteger.TEN.pow(N>>1);  

28.                 BigInteger half = n.divide(one0);  

29.                 if (N<=2){  

30.                     if (N==1){  

31.                         ans[++A] = n;  

32.                         n = BigInteger.ZERO;  

33.                         break;  

34.                     }else {//2 wei  

35.                         if (n.compareTo(BigInteger.valueOf(19))==0){  

36.                             ans[++A] = BigInteger.valueOf(11);  

37.                             ans[++A] = BigInteger.valueOf( 8);  

38.                             n = BigInteger.ZERO;  

39.                             break;  

40.                         }else if (n.compareTo(BigInteger.valueOf(19))==-1){  

41.                             ans[++A] = BigInteger.valueOf(9);  

42.                             ans[++A] = n.subtract(BigInteger.valueOf(9));  

43.                             n = BigInteger.ZERO;  

44.                             break;  

45.                         }//else continue;  

46.                     }  

47.                 }  

48.                 half = half.subtract(BigInteger.ONE);  

49.                 //System.out.println("half=" + half);  

50.                 BigInteger fan = fanzhuan(half);  

51.                 if (N%2>0) fan = fan.mod(one0);  

52.                 //System.out.println("fan=" + fan);  

53.                 BigInteger jan = half.multiply(one0).add(fan);  

54.                 //System.out.println("jan=" + jan);  

55.                 ans[++A] = jan ;  

56.                 n = n.subtract(jan);  

57.                 N = String.valueOf(n).length();  

58.             }  

59.             if (n.compareTo(BigInteger.ZERO)==1)ans[++A] = n;  

60.             System.out.printf("Case #%d:\n%d\n",cas,A);  

61.             for (int i=1;i<=A;i++){  

62.                 System.out.println(ans[i]);  

63.             }  

64.         }  

65.         cin.close();  

66.     }  

67. }  

高精度

(一)BigDecimal类的常用的几个构造方法

·        BigDecimal(int):将int表示形式转换为BigDecimal对象

·        BigDecimal(String) :将字符串表示形式转换为BigDecimal对象

·        BigDecimal(double):将double表示形式转换为BigDecimal对象

 

(二)BigDecimal类的常用方法

·        add(BigDecimal)BigDecimal对象中的值相加,返回BigDecimal对象

·        subtract(BigDecimal)BigDecimal对象中的值相减,返回BigDecimal对象

·        multiply(BigDecimal)BigDecimal对象中的值相乘,返回BigDecimal对象

·        divide(BigDecimal)BigDecimal对象中的值相除,返回BigDecimal对象

·        toString():将BigDecimal对象中的值转换成字符串

·        doubleValue():将BigDecimal对象中的值转换成双精度数

·        floatValue():将BigDecimal对象中的值转换成单精度数

·        longValue():将BigDecimal对象中的值转换成长整数

·        intValue():将BigDecimal对象中的值转换成整数

 

下面分享一个用于高精确处理常用的数学运算类

1.  package com.per.test;  

2.    

3.  import java.math.BigDecimal;  

4.    

5.  /** 

6.   * 用于高精确处理常用的数学运算 

7.   * Created by lijuan on 2016/8/27. 

8.   */  

9.  public class ArithmeticUtils {  

10.     //默认除法运算精度  

11.     private static final int DEF_DIV_SCALE = 10;  

12.   

13.     /** 

14.      * 提供精确的加法运算 

15.      * 

16.      * @param v1 被加数 

17.      * @param v2 加数 

18.      * @return 两个参数的和 

19.      */  

20.   

21.     public static double add(double v1, double v2) {  

22.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  

23.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  

24.         return b1.add(b2).doubleValue();  

25.     }  

26.   

27.     /** 

28.      * 提供精确的加法运算 

29.      * 

30.      * @param v1 被加数 

31.      * @param v2 加数 

32.      * @return 两个参数的和 

33.      */  

34.     public static BigDecimal add(String v1, String v2) {  

35.         BigDecimal b1 = new BigDecimal(v1);  

36.         BigDecimal b2 = new BigDecimal(v2);  

37.         return b1.add(b2);  

38.     }  

39.   

40.     /** 

41.      * 提供精确的加法运算 

42.      * 

43.      * @param v1    被加数 

44.      * @param v2    加数 

45.      * @param scale 保留scale 位小数 

46.      * @return 两个参数的和 

47.      */  

48.     public static String add(String v1, String v2, int scale) {  

49.         if (scale < 0) {  

50.             throw new IllegalArgumentException(  

51.                     "The scale must be a positive integer or zero");  

52.         }  

53.         BigDecimal b1 = new BigDecimal(v1);  

54.         BigDecimal b2 = new BigDecimal(v2);  

55.         return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  

56.     }  

57.   

58.     /** 

59.      * 提供精确的减法运算 

60.      * 

61.      * @param v1 被减数 

62.      * @param v2 减数 

63.      * @return 两个参数的差 

64.      */  

65.     public static double sub(double v1, double v2) {  

66.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  

67.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  

68.         return b1.subtract(b2).doubleValue();  

69.     }  

70.   

71.     /** 

72.      * 提供精确的减法运算。 

73.      * 

74.      * @param v1 被减数 

75.      * @param v2 减数 

76.      * @return 两个参数的差 

77.      */  

78.     public static BigDecimal sub(String v1, String v2) {  

79.         BigDecimal b1 = new BigDecimal(v1);  

80.         BigDecimal b2 = new BigDecimal(v2);  

81.         return b1.subtract(b2);  

82.     }  

83.   

84.     /** 

85.      * 提供精确的减法运算 

86.      * 

87.      * @param v1    被减数 

88.      * @param v2    减数 

89.      * @param scale 保留scale 位小数 

90.      * @return 两个参数的差 

91.      */  

92.     public static String sub(String v1, String v2, int scale) {  

93.         if (scale < 0) {  

94.             throw new IllegalArgumentException(  

95.                     "The scale must be a positive integer or zero");  

96.         }  

97.         BigDecimal b1 = new BigDecimal(v1);  

98.         BigDecimal b2 = new BigDecimal(v2);  

99.         return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  

100.     }  

101.   

102.     /** 

103.      * 提供精确的乘法运算 

104.      * 

105.      * @param v1 被乘数 

106.      * @param v2 乘数 

107.      * @return 两个参数的积 

108.      */  

109.     public static double mul(double v1, double v2) {  

110.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  

111.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  

112.         return b1.multiply(b2).doubleValue();  

113.     }  

114.   

115.     /** 

116.      * 提供精确的乘法运算 

117.      * 

118.      * @param v1 被乘数 

119.      * @param v2 乘数 

120.      * @return 两个参数的积 

121.      */  

122.     public static BigDecimal mul(String v1, String v2) {  

123.         BigDecimal b1 = new BigDecimal(v1);  

124.         BigDecimal b2 = new BigDecimal(v2);  

125.         return b1.multiply(b2);  

126.     }  

127.   

128.   

129.     /** 

130.      * 提供精确的乘法运算 

131.      * 

132.      * @param v1    被乘数 

133.      * @param v2    乘数 

134.      * @param scale 保留scale 位小数 

135.      * @return 两个参数的积 

136.      */  

137.     public static double mul(double v1, double v2, int scale) {  

138.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  

139.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  

140.         return round(b1.multiply(b2).doubleValue(), scale);  

141.     }  

142.   

143.     /** 

144.      * 提供精确的乘法运算 

145.      * 

146.      * @param v1    被乘数 

147.      * @param v2    乘数 

148.      * @param scale 保留scale 位小数 

149.      * @return 两个参数的积 

150.      */  

151.     public static String mul(String v1, String v2, int scale) {  

152.         if (scale < 0) {  

153.             throw new IllegalArgumentException(  

154.                     "The scale must be a positive integer or zero");  

155.         }  

156.         BigDecimal b1 = new BigDecimal(v1);  

157.         BigDecimal b2 = new BigDecimal(v2);  

158.         return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  

159.     }  

160.   

161.     /** 

162.      * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 

163.      * 小数点以后10位,以后的数字四舍五入 

164.      * 

165.      * @param v1 被除数 

166.      * @param v2 除数 

167.      * @return 两个参数的商 

168.      */  

169.   

170.     public static double div(double v1, double v2) {  

171.         return div(v1, v2, DEF_DIV_SCALE);  

172.     }  

173.   

174.     /** 

175.      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 

176.      * 定精度,以后的数字四舍五入 

177.      * 

178.      * @param v1    被除数 

179.      * @param v2    除数 

180.      * @param scale 表示表示需要精确到小数点以后几位。 

181.      * @return 两个参数的商 

182.      */  

183.     public static double div(double v1, double v2, int scale) {  

184.         if (scale < 0) {  

185.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  

186.         }  

187.         BigDecimal b1 = new BigDecimal(Double.toString(v1));  

188.         BigDecimal b2 = new BigDecimal(Double.toString(v2));  

189.         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();  

190.     }  

191.   

192.     /** 

193.      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 

194.      * 定精度,以后的数字四舍五入 

195.      * 

196.      * @param v1    被除数 

197.      * @param v2    除数 

198.      * @param scale 表示需要精确到小数点以后几位 

199.      * @return 两个参数的商 

200.      */  

201.     public static String div(String v1, String v2, int scale) {  

202.         if (scale < 0) {  

203.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  

204.         }  

205.         BigDecimal b1 = new BigDecimal(v1);  

206.         BigDecimal b2 = new BigDecimal(v1);  

207.         return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();  

208.     }  

209.   

210.     /** 

211.      * 提供精确的小数位四舍五入处理 

212.      * 

213.      * @param v     需要四舍五入的数字 

214.      * @param scale 小数点后保留几位 

215.      * @return 四舍五入后的结果 

216.      */  

217.     public static double round(double v, int scale) {  

218.         if (scale < 0) {  

219.             throw new IllegalArgumentException("The scale must be a positive integer or zero");  

220.         }  

221.         BigDecimal b = new BigDecimal(Double.toString(v));  

222.         return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();  

223.     }  

224.   

225.     /** 

226.      * 提供精确的小数位四舍五入处理 

227.      * 

228.      * @param v     需要四舍五入的数字 

229.      * @param scale 小数点后保留几位 

230.      * @return 四舍五入后的结果 

231.      */  

232.     public static String round(String v, int scale) {  

233.         if (scale < 0) {  

234.             throw new IllegalArgumentException(  

235.                     "The scale must be a positive integer or zero");  

236.         }  

237.         BigDecimal b = new BigDecimal(v);  

238.         return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  

239.     }  

240.   

241.   

242.     /** 

243.      * 取余数 

244.      * 

245.      * @param v1    被除数 

246.      * @param v2    除数 

247.      * @param scale 小数点后保留几位 

248.      * @return 余数 

249.      */  

250.     public static String remainder(String v1, String v2, int scale) {  

251.         if (scale < 0) {  

252.             throw new IllegalArgumentException(  

253.                     "The scale must be a positive integer or zero");  

254.         }  

255.         BigDecimal b1 = new BigDecimal(v1);  

256.         BigDecimal b2 = new BigDecimal(v2);  

257.         return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();  

258.     }  

259.   

260.     /** 

261.      * 取余数  BigDecimal 

262.      * 

263.      * @param v1    被除数 

264.      * @param v2    除数 

265.      * @param scale 小数点后保留几位 

266.      * @return 余数 

267.      */  

268.     public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {  

269.         if (scale < 0) {  

270.             throw new IllegalArgumentException(  

271.                     "The scale must be a positive integer or zero");  

272.         }  

273.         return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);  

274.     }  

275.   

276.     /** 

277.      * 比较大小 

278.      * 

279.      * @param v1 被比较数 

280.      * @param v2 比较数 

281.      * @return 如果v1 大于v2  返回true 否则false 

282.      */  

283.     public static boolean compare(String v1, String v2) {  

284.         BigDecimal b1 = new BigDecimal(v1);  

285.         BigDecimal b2 = new BigDecimal(v2);  

286.         int bj = b1.compareTo(b2);  

287.         boolean res;  

288.         if (bj > 0)  

289.             res = true;  

290.         else  

291.             res = false;  

292.         return res;  

293.     }  

294. }  

某次多校做的题

1.  import java.math.BigDecimal;  

2.  import java.util.Scanner;  

3.    

4.  public class Main {  

5.    

6.      public static void main(String[] args) {  

7.      String x1, y1, x2, y2, x3, y3, tx, ty;  

8.      //BigDecimal  

9.      String cx, cy;  

10.     Scanner in = new Scanner(System.in);  

11.     int t;  

12.     t = in.nextInt();  

13.     while((t--) > 0) {  

14.         x1 = in.next();  

15.         y1 = in.next();  

16.         x2 = in.next();  

17.         y2 = in.next();  

18.         x3 = in.next();  

19.         y3 = in.next();  

20.         tx = in.next();  

21.         ty = in.next();  

22.         // point 1  

23.         BigDecimal a1 = new BigDecimal(x1);  

24.         BigDecimal b1 = new BigDecimal(y1);  

25.         BigDecimal c1 = new BigDecimal("1");  

26.         BigDecimal ta1 = a1.multiply(a1);  

27.         BigDecimal tb1 = b1.multiply(b1);  

28.         BigDecimal tp1 = ta1.add(tb1);  

29.         BigDecimal d1 = tp1.multiply(new BigDecimal(-1));  

30.         // point 2  

31.                 BigDecimal a2 = new BigDecimal(x2);  

32.                 BigDecimal b2 = new BigDecimal(y2);  

33.                 BigDecimal c2 = new BigDecimal("1");  

34.                 BigDecimal ta2 = a2.multiply(a2);  

35.                 BigDecimal tb2 = b2.multiply(b2);  

36.                 BigDecimal tp2 = ta2.add(tb2);  

37.                 BigDecimal d2 = tp2.multiply(new BigDecimal(-1));  

38.         // point 3  

39.                 BigDecimal a3 = new BigDecimal(x3);  

40.                 BigDecimal b3 = new BigDecimal(y3);  

41.                 BigDecimal c3 = new BigDecimal("1");  

42.                 BigDecimal ta3 = a3.multiply(a3);  

43.                 BigDecimal tb3 = b3.multiply(b3);  

44.                 BigDecimal tp3 = ta3.add(tb3);  

45.                 BigDecimal d3 = tp3.multiply(new BigDecimal(-1));  

46.         BigDecimal g1 = d1.multiply(c2).subtract(d2.multiply(c1));  

47.         BigDecimal g2 = b2.multiply(c3).subtract(b3.multiply(c2));       

48.         BigDecimal g3 = d2.multiply(c3).subtract(d3.multiply(c2));//(d2*c3-d3*c2)  

49.         BigDecimal g4 = b1.multiply(c2).subtract(b2.multiply(c1));//(b1*c2-b2*c1)  

50.           

51.         BigDecimal g5 = a1.multiply(c2).subtract(a2.multiply(c1));//(a1*c2-a2*c1)  

52.         BigDecimal g6 = b2.multiply(c3).subtract(b3.multiply(c2));//(b2*c3-b3*c2)  

53.           

54.         BigDecimal g7 = a2.multiply(c3).subtract(a3.multiply(c2));//(a2*c3-a3*c2)  

55.         BigDecimal g8 = b1.multiply(c2).subtract(b2.multiply(c1));//(b1*c2-b2*c1)  

56.           

57.         g1 = g1.multiply(g2).subtract(g3.multiply(g4));  

58.         g2 = g5.multiply(g6).subtract(g7.multiply(g8));  

59.         BigDecimal x = g1.divide(g2);  

60.           

61.           

62.         //yyyyyyyyyyyyyyyy  

63.         BigDecimal gg1 = d1.multiply(c2).subtract(d2.multiply(c1));  

64.         BigDecimal gg2 = a2.multiply(c3).subtract(a3.multiply(c2));  

65.         BigDecimal gg3 = d2.multiply(c3).subtract(d3.multiply(c2));  

66.         BigDecimal gg4 = a1.multiply(c2).subtract(a2.multiply(c1));  

67.         BigDecimal gg5 = a2.multiply(c3).subtract(a3.multiply(c2));  

68.         BigDecimal gg6 = b1.multiply(c2).subtract(b2.multiply(c1));  

69.         BigDecimal gg7 = a1.multiply(c2).subtract(a2.multiply(c1));  

70.         BigDecimal gg8 = b2.multiply(c3).subtract(b3.multiply(c2));  

71.   

72.         BigDecimal y = (gg1.multiply(gg2).subtract(gg3.multiply(gg4))).divide(gg5.multiply(gg6).subtract(gg7.multiply(gg8)));  

73.   

74.         //zzzzzzzzzzzzzzzzz  

75.         BigDecimal z = d1.subtract(a1.multiply(x)).subtract(b1.multiply(y)).divide(c1);  

76.         System.out.println(x.toString());  

77.         System.out.println(y.toString());  

78.         System.out.println(z.toString());  

79.           

80.         BigDecimal btx = new BigDecimal(tx);  

81.         BigDecimal bty = new BigDecimal(ty);  

82.         BigDecimal btx2 = btx.multiply(btx);  

83.         BigDecimal bty2 = bty.multiply(bty);  

84.         BigDecimal oth = btx2.add(bty2).add(z);  

85.           

86.         BigDecimal didi = btx.multiply(x);  

87.         BigDecimal eiei = bty.multiply(y);  

88.           

89.         oth = oth.add(didi).add(eiei);  

90.         if(oth.compareTo(new BigDecimal("0")) <= 0) {  

91.             System.out.println("Rejected");  

92.         }  

93.         else System.out.println("Accepted");  

94.     }  

95.     }  

96. }  

五、树状数组

修改(查询)某点的值,区间求和(区间更新),O(N*M)(区间长度N,M次操作),树状数组的话就是O(NlogM)

 

模板:

1.  int lowbit(int k)  

2.  {  

3.      return k & (-k);  

4.  }  

5.  void add(int k,int x)  

6.  {  

7.      while(k <= n){  

8.          c[k] += x;  

9.          k += lowbit(k);  

10.     }  

11. }  

12. int getsum(int k)  

13. {  

14.     int sum = 0;  

15.     while(k > 0){  

16.         sum += c[k];  

17.         k -= lowbit(k);  

18.     }   

19.     return sum;  

20. }  

 

例题:求逆序对。(poj2299)

1.  #include <cstdio>  

2.  #include <iostream>  

3.  #include <cstring>  

4.  #include <algorithm>  

5.  using namespace std;  

6.  typedef long long LL;  

7.  #define FOR(i, a, b) for(LL i = (a); i <(b); ++i)  

8.  const LL N = (LL)1e6 + 7;  

9.  int c[N], n, aa[N];   

10. struct Node  

11. {  

12.     int v;  

13.     int order;  

14. }a[N];  

15.   

16. bool cmp(Node a, Node b)  

17. {  

18.     return a.v < b.v;  

19. }  

20. int lowbit(int k)  

21. {  

22.     return k & (-k);  

23. }  

24. void add(int k,int x)  

25. {  

26.     while(k <= n){  

27.         c[k] += x;  

28.         k += lowbit(k);  

29.     }  

30. }  

31. int getsum(int k)  

32. {  

33.     int sum = 0;  

34.     while(k > 0){  

35.         sum += c[k];  

36.         k -= lowbit(k);  

37.     }   

38.     return sum;  

39. }  

40.   

41. int main()  

42. {  

43.     while(~scanf("%d", &n), n){  

44.         LL ans = 0;  

45.         memset(c, 0, sizeof(c));  

46.         for (int i = 1; i <= n; i++) {  

47.             scanf("%d", &a[i].v);  

48.             a[i].order = i;  

49.         }  

50.         sort(a + 1, a + n + 1, cmp);  

51.         for (int i = 1; i <= n; i++)  

52.             aa[a[i].order] = i;  

53.         for(int i = 1; i <= n; i++){  

54.             add(aa[i], 1);  

55.             ans += i - getsum(aa[i]);//统计当前序列中大于a的元素的个数  

56.         }  

57.         printf("%lld\n", ans);  

58.     }  

59.     return 0;  

60. }  

六、并查集

1.  void init(int n){        //初始化函数  

2.     for(int i=0;i<=n;i++)fa[i]=i;  

3.   }  

4.    

5.  int find(int x){        //寻找祖宗  

6.       return fa[x]==x?x:fa(x)=find(fa[x]);  

7.   }  

8.     

9.   void union(int x,int y){    //合并两点  

10.      int dx=find(x),dy=find(y);  

11.     if(dx!=dy)fa[dx]=dy;  

12. }  

七、数论

欧拉函数

1.  LL euler(LL x){      

2.      if(x<2){  

3.          return 0;  

4.      }  

5.      int ans=1;  

6.      for(int i=2; i*i<=x; i++){  

7.          if(x%i==0){  

8.              ans*=i-1;  

9.              x/=i;  

10.         }  

11.         while(x%i==0){  

12.             x/=i;  

13.             ans*=i;     

14.         }  

15.     }  

16.     if(x>1){  

17.         ans*=x-1;  

18.     }  

19.     return ans;  

20. }  

莫比乌斯函数

1.  void Init(){  

2.      memset(vis,0,sizeof(vis));  

3.      mu[1] = 1;  

4.      cnt = 0;  

5.      for(int i=2; i<N; i++){  

6.          if(!vis[i]){  

7.              prime[cnt++] = i;  

8.              mu[i] = -1;  

9.          }  

10.         for(int j=0; j<cnt&&i*prime[j]<N; j++){  

11.             vis[i*prime[j]] = 1;  

12.             if(i%prime[j]) mu[i*prime[j]] = -mu[i];  

13.             else{  

14.                 mu[i*prime[j]] = 0;  

15.                 break;  

16.             }  

17.         }  

18.     }  

19. }  

欧拉筛

1.  #include <cstring>  

2.  using namespace std;  

3.  int prime[1100000], primesize, phi[11000000];  

4.  bool isprime[11000000];    

5.  void getlist(int listsize){      

6.      memset(isprime, 1, sizeof(isprime));       

7.      isprime[1] = false;       

8.      for(int i = 2;i <= listsize; i++){           

9.          if(isprime[i]) prime[++primesize] = i;            

10.         for(int j = 1; j <= primesize && i * prime[j] <= listsize; j++){            

11.             isprime[i*prime[j]] = false;               

12.             if(i % prime[j] == 0) break;            

13.         }       

14.     }  

15. }  

快速幂

1.  #include <bits/stdc++.h>  

2.  using namespace std;  

3.  typedef long long LL;  

4.  LL fast_multi(LL m, LL n, LL mod){//快速乘法  

5.      LL ans = 0;//注意初始化是 0,不是 1      

6.      for( ;n; n >>= 1){         

7.           if (n & 1) ans += m;     

8.           m = (m + m) % mod;//和快速幂一样,只不过这里是加       

9.           m %= mod;//取模,不要超出范围        

10.          ans %= mod;      

11.     }      

12.     return ans;  

13. }  

14. LL fast_pow(LL a, LL n, LL mod){//快速幂        

15.     LL ans = 1;       

16.     for(;n;n >>= 1){           

17.         if (n & 1) ans = fast_multi(ans, a, mod);//不能直接乘         

18.            a = fast_multi(a, a, mod);        

19.         ans %= mod;         

20.         a %= mod;        `  

21.     }  

22.     return ans;  

23. }  

24. int main(){  

25.     cout << fast_multi(2, 3, 10) << endl;  

26. }  

乘法逆元

欧几里得算法

1.  #include <cstdio>  

2.    

3.  int gcd(int a, int b){  

4.      return a % b ? gcd(b, a % b) : b;  

5.  }   

6.  void exGcd(int a,int b,int &x,int &y){    

7.      if(b==0){    

8.          x=1;y=0;    

9.          return ;    

10.     }    

11.     exGcd(b,a%b,x,y);    

12.         int temp;    

13.         temp=y;    

14.         y=x-a/b*y;    

15.         x=temp;    

16. }    

17. int main(){  

18.     int m, n;  

19.     int x,y;  

20.     while(~scanf("%d%d", &m, &n)){  

21.         exGcd(m, n, x, y);  

22.         printf("%d %d %d\n", gcd(m, n), x, y);  

23.     }  

24.     return 0;  

25. }  

 

八、动态规划

LIS(最长上升子序列)

1.  int lis()  

2.  {  

3.      memset(dp, 0, sizeof(dp));  

4.      int Max;  

5.      for (int i = 0; i < n; ++i)  

6.      {  

7.          Max = 0;  

8.          for (int j = 0; j < i; ++j)  

9.          {  

10.             if (a[i] > a[j])  

11.             {  

12.                 Max = max(Max, dp[j]);  

13.             }  

14.         }  

15.         dp[i] = Max + 1;  

16.     }  

17.     Max = 0;  

18.     for (int i = 0; i < n; ++i)  

19.     {  

20.         if (dp[i] > Max)    Max = dp[i];  

21.     }  

22.     return Max;  

23. }  

 

1.  int lis()  

2.  {  

3.      memset(dp, 0, sizeof(int)*n);  

4.      int len = 1;  

5.      dp[0] = a[0];  

6.      for (int i = 1; i < n; ++i)  

7.      {  

8.          int pos = lower_bound(dp, dp + len, a[i]) - dp;  

9.          dp[pos] = a[i];  

10.         len = max(len, pos + 1);  

11.     }  

12.     return len;  

13. }  

LCS(最长公共子序列)

1.  public static int lcs(String str1, String str2) {  

2.      int len1 = str1.length();  

3.      int len2 = str2.length();  

4.      int c[][] = new int[len1+1][len2+1];  

5.      for (int i = 0; i <= len1; i++) {  

6.          forint j = 0; j <= len2; j++) {  

7.              if(i == 0 || j == 0) {  

8.                  c[i][j] = 0;  

9.              } else if (str1.charAt(i-1) == str2.charAt(j-1)) {  

10.                 c[i][j] = c[i-1][j-1] + 1;  

11.             } else {  

12.                 c[i][j] = max(c[i - 1][j], c[i][j - 1]);  

13.             }  

14.         }  

15.     }  

16.     return c[len1][len2];  

17. }  

最长公共子串

1.  public static int lcs(String str1, String str2) {  

2.      int len1 = str1.length();  

3.      int len2 = str2.length();  

4.      int result = 0;     //记录最长公共子串长度  

5.      int c[][] = new int[len1+1][len2+1];  

6.      for (int i = 0; i <= len1; i++) {  

7.          forint j = 0; j <= len2; j++) {  

8.              if(i == 0 || j == 0) {  

9.                  c[i][j] = 0;  

10.             } else if (str1.charAt(i-1) == str2.charAt(j-1)) {  

11.                 c[i][j] = c[i-1][j-1] + 1;  

12.                 result = max(c[i][j], result);  

13.             } else {  

14.                 c[i][j] = 0;  

15.             }  

16.         }  

17.     }  

18.     return result;  

19. }  

背包问题

1.  #include<stdio.h>  

2.  #include<iostream>  

3.  #include<cstring>  

4.  using namespace std;  

5.     

6.  int main(){  

7.      int t, n, M, w[30], p[30], dp[100005] = {-1};  

8.      cin >> t;  

9.      while(t--){  

10.         memset(dp,0,sizeof(dp));  

11.     //  cout << dp[10] << endl;  

12.         cin >> n >> M;  

13.         forint i = 0; i < n; i++ )  

14.         cin >> w[i] >> p[i];  

15.      forint i = 0; i < n; i++ )    

16.     {    

17.         //因为使用了一维数组,所有j要按照递减顺序    

18.         forint j = M; j >= w[i]; j-- )    

19.         {               

20.             if( dp[j-w[i]] + p[i] > dp[j] )    

21.                 dp[j] = dp[j-w[i]] + p[i];             

22.         }    

23.     }    

24.     cout << dp[M] << endl;    

25.     }  

26. }  

 

九、线段树

模板一

1.  #include <cstdio>  

2.  #include <iostream>  

3.    

4.  using namespace std;  

5.  #define lson l, m, rt << 1  

6.  #define rson m + 1, r, rt << 1 | 1  

7.  const int maxn = 55555;  

8.  int sum[maxn << 2];  

9.  void PushUP(int rt){  

10.     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];  

11. }  

12. void build(int l, int r, int rt){  

13.     if(l == r){  

14.         scanf("%d", &sum[rt]);  

15.         return ;  

16.     }  

17.     int m = (l + r) >> 1;  

18.     build(lson);  

19.     build(rson);  

20.     PushUP(rt);  

21. }  

22. void update(int p, int add, int l, int r, int rt){  

23.     if(l == r) {  

24.         sum[rt] += add;  

25.         return ;  

26.     }  

27.     int m = (l + r) >> 1;  

28.     if(p <= m) update(p, add, lson);  

29.     else update(p, add, rson);  

30.     PushUP(rt);   

31. }  

32. int query(int L, int R, int l, int r, int rt){  

33.     if(L <= l && r <= R) return sum[rt];  

34.     int m = (l + r) >> 1;  

35.     int ret = 0;  

36.     if(L <= m) ret += query(L, R, lson);  

37.     if(R > m) ret += query(L, R, rson);  

38.     return ret;  

39. }  

40. int main(){  

41.     int t, n;  

42.     scanf("%d", &t);  

43.     for(int cas = 1; cas <= t; cas ++){  

44.         cout << "Case " << cas << ":" << endl;  

45.         scanf("%d", &n);  

46.         build(1, n, 1);  

47.         char op[10];  

48.         while(scanf("%s", op)){  

49.             if(op[0] == 'E'break;  

50.             int a, b;  

51.             scanf("%d%d", &a, &b);  

52.             if(op[0] == 'Q') cout << query(a, b, 1, n, 1) << endl;  

53.             else if(op[0] == 'S') update(a, -b, 1, n, 1);  

54.             else update(a, b, 1, n, 1);  

55.         }  

56.     }  

57. }  

模板二

1.  const int maxn = 100010;  

2.  int n, m, note, a, b;  

3.  struct Segment_Tree{  

4.    int l, r, x;  

5.    bool flag;  

6.  }segTree[maxn * 4 + 10];  

7.     

8.  void build(int note, int be, int en){  

9.     

10.    segTree[note].l = be;  

11.    segTree[note].r = en;  

12.    if(be == en)return;  

13.         build(2 * note, be, (be + en) / 2);  

14.         build(2 * note + 1, (be + en) / 2 + 1, en);  

15.      

16. }  

17. void pushup(int x){  

18.  segTree[x].x = segTree[x * 2].x + segTree[x * 2 + 1].x;  

19. }  

20. void pushdown(int x){  

21.     if(segTree[x].flag){  

22.         segTree[x].flag = 0;  

23.         if(segTree[x].l < segTree[x].r){  

24.             segTree[x * 2].flag ^= 1;  

25.             segTree[x * 2 + 1].flag ^= 1;  

26.         }  

27.         segTree[x].x = segTree[x].r - segTree[x].l + 1 - segTree[x].x;  

28.     }  

29. }  

30. void add(int note, int a, int b){  

31.    if(segTree[note].l == a && segTree[note].r == b){  

32.     segTree[note].flag ^= 1;  

33.     pushdown(note);  

34.     return ;  

35.    }  

36.    pushdown(note);  

37.    int mid = (segTree[note].l + segTree[note].r) / 2;  

38.    if(b <= mid) add(note * 2, a, b), pushdown(note * 2 + 1);  

39.    else if(a > mid) add(note * 2 + 1, a, b), pushdown(note * 2);  

40.    else add(note * 2, a, mid), add(note * 2 + 1, mid + 1, b);  

41.    pushup(note);  

42. }  

43.    

44. int query(int note, int a, int b){  

45.   pushdown(note);  

46.   if(segTree[note].l == a && segTree[note].r == b)  

47.   return segTree[note].x;  

48.   int mid = (segTree[note].l + segTree[note].r) / 2;  

49.   if(b <= mid) return query(note * 2, a, b);  

50.   else if(a > mid) return query(note * 2 + 1, a, b);  

51.   else return query(note * 2, a, mid) + query(note * 2 + 1, mid + 1, b);  

52. }  

53.    

54. int main(){  

55.   scanf("%d%d", &n, &m);  

56.   build(1, 1, n);  

57.   for(int i = 0; i < m; i++){  

58.     scanf("%d%d%d", &note, &a, &b);  

59.     if(note == 0)  

60.         add(1, a, b);  

61.     else  

62.         cout << query(1, a, b) << endl;  

63.    }  

64. }  

十、字符串

KMP算法

1.  void getNext()  

2.  {  

3.      int i=0,j=-1;  

4.      next_[0]=-1;  

5.      while(i<m)  

6.      {  

7.          if(pattern[i]==pattern[j] || j==-1)  

8.          {  

9.              i++,j++;  

10.             if(pattern[i]!=pattern[j])  

11.                 next_[i]=j;  

12.             else  

13.                 next_[i]=next_[j];  

14.         }  

15.         else  

16.             j=next_[j];  

17.     }  

18. }  

19.   

20.   

21. void findNext()  

22. {  

23.     int i=0,j=0;  

24.     while(i<n && j<m)  

25.         if(pattern[j]==text[i] || j==-1)  

26.             i++,j++;  

27.         else  

28.             j=next_[j];  

29.     if(j==m)  

30.         printf("%d\n",i-m+1);  

31.     else  

32.         printf("-1\n");  

33. }  

Trie

1.  Trie树  

2.  #include <iostream>  

3.  #include <cstdio>  

4.  #include <cstdlib>  

5.  #include <cstring>  

6.  #include <algorithm>  

7.  #include <iomanip>  

8.    

9.  using namespace std;  

10.   

11. int num;//字符串的总个数  

12.   

13. struct Trie  

14. {  

15.     int cnt;//某个字符串出现的总个数  

16.     char name[30];//保存的字符串  

17.     bool ok;//是不是走到了字符串的最后一个字母,保存最后一个字母的那个节点也保存着整个字符串的Name  

18.     Trie *next[127];//子节点,ASCII最大值为126  

19.     Trie()  

20.     {  

21.         ok=0;  

22.         cnt=0;  

23.         for(int i=0;i<127;i++)  

24.             next[i]=NULL;  

25.     }  

26. }root;  

27.   

28. void create(char s[])  

29. {  

30.     int len=strlen(s);  

31.     Trie*p=&root;  

32.     for(int i=0;i<len;i++)  

33.     {  

34.         int id=s[i];  

35.         if(p->next[id]==NULL)  

36.             p->next[id]=new Trie;  

37.         p=p->next[id];  

38.     }  

39.     p->cnt++;//走到字符串的最后一个字母的节点  

40.     strcpy(p->name,s);  

41.     p->ok=1;  

42. }  

43.   

44. void dfs(Trie *root)//递归输出  

45. {  

46.     Trie*p=root;  

47.     if(p->ok)  

48.         cout<<p->name<<" "<<setiosflags(ios::fixed)<<setprecision(4)<<100.0*p->cnt/num<<endl;  

49.     for(int i=0;i<127;i++){  

50.         if(p->next[i]!=NULL){  

51.             dfs(p->next[i]);  

52.         }  

53.     }  

54. }  

55.   

56. char s[30];  

57.   

58. int main()  

59. {  

60.       

61.     while(gets(s)){  

62.         create(s);  

63.         num++;  

64.     }  

65.     dfs(&root);  

66.     return 0;  

67. }  

 

十一、图论

Floyd

1.  #include <iostream>  

2.  #include <cstdio>  

3.  #include <cstring>  

4.  #include <map>  

5.  using namespace std;  

6.  const int INF = 0x3f3f3f3f;  

7.      int n;  

8.      double cost, e[110][110];  

9.      string s1, s2;  

10.     int m;  

11. map<string, int> mp;  

12.    

13. void Folyd()    

14. {    

15.     for(int k = 1; k <= n; k++)    

16.         for(int i = 1; i <= n; i++)    

17.             for(int j = 1; j <= n; j++)    

18.             {    

19.                 if(e[i][j] > e[i][k] + e[k][j])   //松弛操作   

20.                     e[i][j] = e[i][k] + e[k][j];    

21.             }    

22.     

23. }     

24. void init()    

25. {    

26.     for(int i = 1; i <= n; i++)    

27.         for(int j = 1; j <= n; j++)    

28.         {    

29.             if(i == j)    

30.                 e[i][j] = 0;  

31.             else    

32.                 e[i][j] = INF;  

33.         }    

34. }    

35.   int main(){  

36. scanf("%d%d", &n, &m);      

37.     init();  

38.     int cas = 1;  

39.     for(int i = 0; i < m; i++){  

40.         cin >> s1 >> s2 >> cost;  

41.     if(mp[s1] == 0)mp[s1] = cas++;  

42.     if(mp[s2] == 0)mp[s2] = cas++;  

43. e[mp[s2]][mp[s1]] =  e[mp[s1]][mp[s2]] = cost;  

44.     }  

45.         Folyd();  

46.         int t;  

47. scanf("%d", &t);  

48. for(int i = 0; i < t; i++){  

49.     cin >> s1 >> s2;  

50.   if(e[mp[s1]][mp[s2]] < INF && mp[s1] && mp[s2]) cout << e[mp[s1]][mp[s2]] << endl;  

51.   else cout << "-1" << endl;   

52.     }  

53. }  

DIJ迪杰斯特拉

1.  #include <iostream>  

2.  using namespace std;  

3.     

4.  const int maxnum = 100;  

5.  const int maxint = 999999;  

6.     

7.     

8.  void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum])  

9.  {  

10.     bool s[maxnum];    // 判断是否已存入该点到S集合中  

11.     for(int i=1; i<=n; ++i)  

12.     {  

13.         dist[i] = c[v][i];  

14.         s[i] = 0;     // 初始都未用过该点  

15.         if(dist[i] == maxint)  

16.             prev[i] = 0;  

17.         else  

18.             prev[i] = v;  

19.     }  

20.     dist[v] = 0;  

21.     s[v] = 1;  

22.    

23.     // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S  

24.     // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度  

25.     for(int i=2; i<=n; ++i)  

26.     {  

27.         int tmp = maxint;  

28.         int u = v;  

29.         // 找出当前未使用的点jdist[j]最小值  

30.         for(int j=1; j<=n; ++j)  

31.             if((!s[j]) && dist[j]<tmp)  

32.             {  

33.                 u = j;              // u保存当前邻接点中距离最小的点的号码  

34.                 tmp = dist[j];  

35.             }  

36.         s[u] = 1;    // 表示u点已存入S集合中  

37.    

38.         // 更新dist  

39.         for(int j=1; j<=n; ++j)  

40.             if((!s[j]) && c[u][j]<maxint)  

41.             {  

42.                 int newdist = dist[u] + c[u][j];  

43.                 if(newdist < dist[j])  

44.                 {  

45.                     dist[j] = newdist;  

46.                     prev[j] = u;  

47.                 }  

48.             }  

49.     }  

50. }  

51.    

52. void searchPath(int *prev,int v, int u)  

53. {  

54.     int que[maxnum];  

55.     int tot = 1;  

56.     que[tot] = u;  

57.     tot++;  

58.     int tmp = prev[u];  

59.     while(tmp != v)  

60.     {  

61.         que[tot] = tmp;  

62.         tot++;  

63.         tmp = prev[tmp];  

64.     }  

65.     que[tot] = v;  

66.     for(int i=tot; i>=1; --i)  

67.         if(i != 1)  

68.             cout << que[i] << " -> ";  

69.         else  

70.             cout << que[i] << endl;  

71. }  

72.    

73. int main()  

74. {  

75.     freopen("input.txt""r", stdin);  

76.     // 各数组都从下标1开始  

77.     int dist[maxnum];     // 表示当前点到源点的最短路径长度  

78.     int prev[maxnum];     // 记录当前点的前一个结点  

79.     int c[maxnum][maxnum];   // 记录图的两点间路径长度  

80.     int n, line;             // 图的结点数和路径数  

81.    

82.     // 输入结点数  

83.     cin >> n;  

84.     // 输入路径数  

85.     cin >> line;  

86.     int p, q, len;          // 输入p, q两点及其路径长度  

87.    

88.     // 初始化c[][]maxint  

89.     for(int i=1; i<=n; ++i)  

90.         for(int j=1; j<=n; ++j)  

91.             c[i][j] = maxint;  

92.    

93.     for(int i=1; i<=line; ++i)    

94.     {  

95.         cin >> p >> q >> len;  

96.         if(len < c[p][q])       // 有重边  

97.         {  

98.             c[p][q] = len;      // p指向q  

99.             c[q][p] = len;      // q指向p,这样表示无向图  

100.         }  

101.     }  

102.    

103.     for(int i=1; i<=n; ++i)  

104.         dist[i] = maxint;  

105.     for(int i=1; i<=n; ++i)  

106.     {  

107.         for(int j=1; j<=n; ++j)  

108.             printf("%8d", c[i][j]);  

109.         printf("/n");  

110.     }  

111.    

112.     Dijkstra(n, 1, dist, prev, c);  

113.    

114.     // 最短路径长度  

115.     cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;  

116.    

117.     // 路径  

118.     cout << "源点到最后一个顶点的路径为: ";  

119.     searchPath(prev, 1, n);  

120. }  

最小生成树

1.  最小生成树prim  

2.  #include <iostream>  

3.  #include <cstdio>  

4.  #include <cmath>  

5.  #include <cstring>   

6.  using namespace std;  

7.  int n, m, x, y;  

8.  double cost, e[1005][1005], mincost[1005];  

9.  bool vis[1005];  

10. struct node{  

11.     int x, y;  

12. }v[1005];  

13. const int INF = 0x3f3f3f3f;  

14.    

15. double prim(){  

16.     double sum = 0;  

17.     while(1){  

18.         int vv;  

19.         double mn = INF;  

20.         for(int i = 1; i <= n; i++){  

21.             if(!vis[i] && mn > mincost[i]) {  

22.                 vv = i;  

23.                 mn = mincost[i];  

24.                 //cout << mn << endl;  

25.             }  

26.         }  

27.         if(mn == INF)break;  

28.         sum += mn;  

29.         vis[vv] = true;  

30.     //  cout << vv << endl;   

31.         for(int i = 1; i <= n; i++){  

32.             if(mincost[i] > e[vv][i]){  

33.                 mincost[i] = e[vv][i];  

34.             }  

35.         }  

36.     }  

37.     return sum;  

38. }  

39. int main(){  

40. for(int i = 0; i < 1005; i++){  

41.     mincost[i] = INF;  

42. }  

43.     memset(vis, falsesizeof(vis));  

44.     mincost[1] = 0;  

45.     scanf("%d%d", &n, &m);  

46.     for(int i = 1; i <= n; i++){  

47.     scanf("%d%d", &v[i].x, &v[i].y);  

48.     for(int j = 1; j < i; j++){  

49.         cost = sqrt((double)(v[i].x - v[j].x) * (v[i].x - v[j].x)   

50.         + (double)(v[i].y - v[j].y) * (v[i].y - v[j].y));  

51.         e[i][j] = e[j][i] = cost;  

52.     }     

53.     }  

54.     for(int i = 0; i < m; i++){  

55.         scanf("%d%d", &x, &y);  

56.         e[x][y] = e[y][x] = 0;  

57.     }  

58. //  cout << mincost[2] << endl;  

59.     printf("%.2f\n", prim());  

60.     return 0;  

61. }  

 

十二、网络流

匈牙利算法,最小点覆盖(最大匹配数)二分图匹配

1.  #include <iostream>  

2.  #include <cstdio>  

3.  #include <algorithm>  

4.  #include <cstring>  

5.  using namespace std;  

6.  int n, m, a, b, nx, ny;  

7.  bool g[510][510], used[510];  

8.  int link[510];  

9.  bool dfs (int u) {    

10.     for (int v = 1; v <= ny; v++) {    

11.         if (!used[v] && g[u][v]) {    

12.             used[v] = true;    

13.             if (link[v] == -1 || dfs (link[v])) {    

14.                 link[v] = u;    

15.                 return true;    

16.             }    

17.         }    

18.     }    

19.     return false;    

20. }     

21. int maxmatch () {    

22.     int res = 0;    

23.     memset (link, -1, sizeof (link));//link[i]=-1表示i不在匹配中,否则(link[i],i)这条边在匹配中    

24.     for (int i = 1; i <= nx; i++) {    

25.         memset (used, falsesizeof (used));    

26.         if (dfs (i)) res++;    

27.     }    

28.     return res;    

29. }    

30.    

31. int main(){  

32.     scanf("%d%d", &n, &m);  

33.         nx = ny = n;  

34.         memset(g, falsesizeof(g));  

35.         for(int i = 0; i < m; i++){  

36.             scanf("%d%d", &a, &b);  

37.             g[a][b] = true;  

38.     }  

39. cout << maxmatch() << endl;  

40.       

41. }  

网络流

见挑战

十三、树

哈夫曼树(二叉搜索树)

1.  哈夫曼树(二叉搜索树)  

2.  oj  

3.  #include <iostream>    

4.  #include <cstdio>  

5.     

6.  using namespace std;    

7.     

8.  int dp[210][210], sum[210][210], a[210],b[210];;    

9.  int n;    

10.    

11. int main()    

12. {    

13.     while(~scanf("%d", &n), n){    

14.         for(int i = 1;i <= n; ++i)    

15.             scanf("%d", &a[i]);    

16.         for(int i = 0; i <= n; ++i)    

17.             scanf("%d", &b[i]);    

18.         for(int i = 1; i <= n; ++i)    

19.             sum[i][i] = a[i] + b[i] + b[i-1];    

20.         for(int d = 1; d < n; ++d)    

21.             for(int  i = 1; i+d <= n; ++i)      

22.                 sum[i][i+d] = sum[i][i+d-1] + a[i+d] + b[i+d];    

23.         for(int i = 1;i <= n+1; ++i){   

24.             sum[i][i-1] = b[i-1];   

25.             dp[i][i-1] = 0;    

26.         }    

27.         for(int d = 0; d < n; ++d)    

28.             for(int i = 1; i+d <= n; ++i){    

29.                 int  j = i + d;    

30.                 int mx = 1000000000;    

31.                 for(int k = i; k <= j;++k)    

32.                     mx = min(mx, dp[i][k-1] + dp[k+1][j]);    

33.                 dp[i][j] = mx + sum[i][j];    

34.             }       

35.         cout << dp[1][n] << endl;  

36.     }    

37.     return 0;       

38. }  

39.   

40. 作业  

41. 问题一:二叉搜索树的建立和中序遍历  

42. 思路:  

43. 本题首先考虑如何从文件中输入和输出,于是想到了输入输出的重定向。  

44. 另外就是二叉搜索树的建立,即考虑插入元素的算法。  

45. 递归实现中序遍历。  

46.   

47. #include <stdio.h>    

48. #include <stdlib.h>    

49. #include <fstream>  

50. typedef int Elemtype;    

51.     

52. typedef struct BiTNode{    

53.     Elemtype data;    

54.     struct BiTNode *lchild, *rchild;    

55. }BiTNode, *BiTree;    

56.     

57. //在给定的BST中插入结点,其数据域为element    

58. int BSTInsert( BiTree *t, Elemtype element )    

59. {    

60.     if( NULL == *t ) {    

61.         (*t) = (BiTree)malloc(sizeof(BiTNode));    

62.         (*t)->data = element;    

63.         (*t)->lchild = (*t)->rchild = NULL;    

64.         return 1;    

65.     }    

66.     

67.     if( element == (*t)->data )    

68.         return 0;    

69.     

70.     if( element < (*t)->data )    

71.         return BSTInsert( &(*t)->lchild, element );    

72.     

73.     return BSTInsert( &(*t)->rchild, element );    

74. }    

75.     

76. //创建BST    

77. void CreateBST( BiTree *t, Elemtype *a, int n )    

78. {    

79.     (*t) = NULL;    

80.     forint i=0; i<n; i++ )    

81.         BSTInsert( t, a[i] );    

82. }    

83.     

84. //中序遍历打印BST    

85. void PrintBST(BiTree t)    

86. {    

87.     if( t ) {    

88.         PrintBST( t->lchild );    

89.         printf("%d\n", t->data);    

90.         PrintBST( t->rchild );    

91.     }    

92. }    

93.    

94. int main()    

95. {    

96.   freopen("C:/Users/dellpc/Desktop/data1w.txt","r",stdin);  //输入输出重定向  

97.   freopen("C:/Users/dellpc/Desktop/out.txt","w",stdout);  

98.     int n;    

99.     int *a;    

100.     BiTree t;    

101.     scanf("%d", &n);    

102.     a = (int *)malloc(sizeof(int)*n);  //申请空间  

103.     forint i=0; i<n; i++ )    

104.         scanf("%d", &a[i]);    

105.     CreateBST(&t, a, n);    

106.     PrintBST(t);     

107.     return 0;    

108. }   

十四、矩阵连乘

1.  矩阵连乘  

2.  #include <iostream>  

3.  #include<algorithm>  

4.  #include<cstring>  

5.  using namespace std;  

6.     

7.  typedef long long ll;  

8.     

9.  ll a[55],b[55],mul[55][55];  

10.    

11. int main()  

12. {  

13.     int N;  

14.     cin >> N;  

15.    //cout << ans << endl;  

16.     while(N--){  

17.         int n,j;  

18.         ll tmp;  

19.         cin >> n;  

20.         for(int i = 0; i < n; i++)  

21.             cin >> a[i] >> b[i];  

22.         memset( mul , 0x7f, sizeof( mul ) );  

23.       //  cout << mul[0][0] << endl;  

24.        for (int i = 0; i < n; ++i )  

25.          mul[ i ][ i ] = 0;  

26.      for (int  len = 1; len < n; ++len )  

27.         for (int  i = 0; i + len < n; ++i ) {  

28.             j = i + len;  

29.          for (int k = i + 1; k <= j; ++k ) {  

30.                         tmp = mul [ i ][ k - 1 ] + mul [ k ][ j ] + a[ i ] * a[ k ] * b[ j ];  

31.                 if ( mul [ i ][ j ] > tmp )  

32.                     mul [ i ][ j ] = tmp;  

33.             }  

34.       }  

35.         cout << mul[0][n - 1] << endl;  

36.     }  

37.     return 0;  

38. }  

39.    

十五、分治法

最近点对

1.  最近点对  

2.    

3.  #include <iostream>  

4.  #include<stdio.h>  

5.  #include<math.h>  

6.  #include<stdlib.h>  

7.  #include<cstdlib>  

8.  #include<cstring>  

9.  #include<algorithm>  

10. using namespace std;  

11.    

12. int n;  

13. struct node{  

14.     double x,y;  

15. }N[100010];  

16.    

17. int cmpx(node a, node b){  

18.     return a.x<b.x;  

19. }  

20. double dis(struct node a,struct node b){  

21.    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));  

22. }  

23. double closest(int low,int high){  

24.          if(low + 1 == high)  

25.             return dis(N[low],N[high]);  

26.          if(low + 2 == high)  

27.             return min(dis(N[low] , N[high]) , min( dis(N[low] , N[low+1]) , dis(N[low+1] , N[high]) ));  

28.          int mid = (low + high)>>1;  

29.    

30.          double ans = min( closest(low , mid) , closest(mid + 1 , high) );  

31.             double sum = dis(N[0],N[1]);  

32.          for(int i=low;i<=mid;i++){  

33.             for(int j=mid+1;j<=high;j++){  

34.                 if((N[j].x-N[i].x)>ans)break;  

35.                 sum = min(sum,dis(N[i],N[j]));  

36.             }  

37.          }  

38.          ans = min(ans,sum);  

39.          return ans;  

40. }  

41. int main()  

42. {  

43.     while(scanf("%d",&n),n){  

44.         for(int i = 0; i < n; i++){  

45.             scanf("%lf%lf",&N[i].x,&N[i].y);  

46.         }  

47.         sort(N,N+n,cmpx);  

48.         printf("%.2f\n",closest(0,n-1)/2);  

49.     }  

50.     return 0;  

51. }  

 

十六、凸包

1.  最小凸包  

2.  #include <cstdio>  

3.  #include <iostream>  

4.  #include <stack>  

5.  #include <cmath>  

6.  #include <cstdlib>   

7.  using namespace std;  

8.  #define pi 3.1415926  

9.  struct NODE{  

10.     double x, y;  

11. }node[1010], result[1010];  

12. int n, top;  

13. double line, dis, my, mx;  

14. int p;  

15. double eps = 1e-10;  

16. stack<NODE> st;  

17. double Distance(NODE p1,NODE p2)          //两点间的距离    

18. {    

19.     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));    

20. }    

21. double Multiply(NODE p1,NODE p2,NODE p3) //叉积    

22. {       

23.    return ((p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x));     

24. }    

25. int Compare(const void *p1,const void *p2) //根据p0->p1的极值和p0->p2的极值进行比较,如果极值相同则用距离长度比较     

26. {    

27.     NODE *p3,*p4;    

28.     double m;    

29.     p3=(NODE *)p1;     

30.     p4=(NODE *)p2;     

31.     m = Multiply(node[0],*p3,*p4) ;    

32.     if(m<0) return 1;    

33.     else if(m < eps && (Distance(node[0],*p3) > Distance(node[0],*p4)))    

34.         return 1;    

35.     else return -1;    

36. }    

37. void GRAHAMSCAN()    

38.    {  

39.    result[0].x=node[0].x;    

40.    result[0].y=node[0].y;    

41.    result[1].x=node[1].x;    

42.    result[1].y=node[1].y;    

43.     result[2].x=node[2].x;    

44.    result[2].y=node[2].y;    

45.    top = 2;  

46.    for(int i=3;i<n;i++)    

47.    {    

48.        while(Multiply(result[top-1],result[top],node[i])<0 && top >= 2) {  

49.         top--;    

50.        }   

51.              

52.        result[top+1].x=node[i].x;    

53.        result[top+1].y=node[i].y;    

54.        top++;    

55.    }    

56.     }    

57.       

58. int main(){  

59.     while(~scanf("%d", &n)){  

60.         dis = 0;  

61.         scanf("%lf", &line);  

62.         for(int i = 0; i < n; i++){  

63.             scanf("%lf%lf", &node[i].x, &node[i].y);  

64.             if(node[i].y < my || (fabs(node[i].y - my) < eps && node[i].x < mx) || i == 0){  

65.             p = i;  

66.             my = node[i].y;  

67.             mx = node[i].x;  

68.             }  

69.         }  

70.           

71.     double temp=node[0].x;    

72.        node[0].x=node[p].x;    

73.        node[p].x=temp;    

74.        temp = node[0].y;    

75.        node[0].y = node[p].y;    

76.        node[p].y = temp;  

77.       qsort(&node[1],n-1,sizeof(double)*2,Compare);  

78.    

79. // for(int i = 0; i < n; i++)cout << node[i].x << " " << node[i].y << endl;  

80.       

81.            

82.       GRAHAMSCAN();  

83.     //  cout << top << endl;  

84.   for(int i=0;i< top ;i++)  {  

85.   //    cout << result[i].x << " " << result[i].y << endl;  

86.       dis=dis+Distance(result[i],result[i+1]);    

87.   }  

88.   dis+= Distance(result[top] , node[0]);  

89.   //cout << dis << endl;  

90.     double s = pi * line * 2;  

91.     printf("%.0f\n", dis + s);  

92.     }  

93. }  

 

十七、解题思路

二分答案+判断(贪心)

 

ECNU计科考研复试机试是上海东华大学计算机科学与技术专业硕士研究生复试环节的一部分。机试一般包括计算机基础知识测试、编程实践、算法设计与分析、数据结构、数据库等内容。 机试的目的是通过实际操作和任务完成,评估考生的计算机基础知识、编程能力和解决问题的能力。机试一般会提供一些实际问题,考生需要根据题目要求进行编程实现,并实现功能要求以及考察的相关知识点。机试的题目会有一定的难度,需要考生具备扎实的计算机基础知识和编程实践经验。 针对ECNU计科考研复试机试的准备,考生可以从以下几个方面进行: 1. 夯实计算机基础知识:系统复习计算机组成原理、操作系统、数据结构、数据库等相关课程的基础知识点,理解并掌握核心概念和原理。 2. 学习编程技巧:熟练掌握至少一种编程语言,例如C++、Java等,并了解常用的编程工具和调试技巧,提高编程能力。 3. 解题经验积累:多做一些编程题和算法题,提高解题能力和编程实践经验。可以通过参加一些线上或线下的编程竞赛来提升自己的算法和编程水平。 4. 多做模拟机试:通过模拟机试,熟悉机试的形式和题目类型,提前感受机试的压力和难度,并对自己的不足进行总结和改进。 总之,ECNU计科考研复试机试是对考生计算机基础知识和编程实践能力的综合考查,需要考生充分准备和深入理解相关知识点。只有全面提高自己的计算机科学水平,才能在机试中取得好成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值