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. }  

 

十七、解题思路

二分答案+判断(贪心)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值