算法竞赛进阶指南第一章题解

例题:CH0103 最短Hamilton路径

题意:

给定一张n(<20)个点的带权无向图,点从0~n-1编号,求起点0到终点n-1的最短hanmilton路径;

h路径的定义为0~n-1不重不漏的经过每个点恰好一次

解法:

二进制状态压缩f(i,j)表示点被经过的状态对应的二进制数为i,且目前处于点j时的最短路径。

最终目标为f((1<<n)-1,n-1)

 1 #include<bits/stdc++.h>
 2 #define REP(i, a, b) for(int i = (a); i < (b); i++)
 3 #define CLR(a) memset(a,0,sizeof(a));
 4 #define MEM(a,x) memset(a,x,sizeof(a)) 
 5 #define ALL(x) begin(x),end(x)
 6 #define LL long long
 7 #define INF 0x3f3f3f3f
 8 #define MAXN 20+1
 9 using namespace std;
10 int f[1 << MAXN][MAXN];
11 int w[MAXN][MAXN];
12 int Hamilton(int n) {
13     MEM(f, 0x3f);
14     f[1][0] = 0;
15     REP(i, 1, 1 << n)REP(j, 0, n)if (i >> j & 1)
16         REP(k, 0, n)if ((i ^ 1 << j) >> k & 1)
17         f[i][j] = min(f[i][j], f[i ^ 1 << j][k] + w[k][j]);
18     return f[(1 << n) - 1][n - 1];
19 }
20 int main() {
21     int n; scanf("%d", &n);
22     REP(i, 0, n)REP(j, 0, n)scanf("%d", &w[i][j]);
23     printf("%d\n", Hamilton(n));
24     return 0;
25 }

BZOJ1218 激光炸弹

题意:

给定平面上的n个点,求一个r*r的正方形最多覆盖多少个点

解法:

维护二维前缀和模板题;

在递推之前要先计算出sum[i][j-1]和sum[i-1][j],之后再递推sum;

之后枚举边长为R的正方形即可

 1 #pragma GCC optimize(3)
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 const double EPS = 1e-9;
 6 const int INF = 2147483647;
 7 const int LLINF = 9223372036854775807;
 8 const double PI = acos(-1.0);
 9 
10 #define     READ(f)       freopen(f, "r", stdin)
11 #define     WRITE(f)      freopen(f, "w", stdout)
12 #define     MP(x, y)      make_pair(x, y)
13 #define     PB(x)         push_back(x)
14 #define     REP(i, a, b)  for(int i = (a); i <= (b); i++)
15 #define     PER(i, a, b)  for(int i = (a); i <= (b); i--)
16 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
17 #define     SET(a)        memset(a,-1,sizeof(a))
18 #define     CLR(a)        memset(a,0,sizeof(a));
19 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
20 #define     ALL(x)        begin(x),end(x)
21 #define     LL            long long
22 #define     Lson          (index * 2)
23 #define     Rson          (index * 2 + 1)
24 #define     pii           pair< int, int >
25 #define     pll           pair< LL, LL >
26 #define     MOD           ((LL)1000000007)
27 #define     MAXN          5000+5
28 
29 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
30 template< class T > inline T sqr(T a) { return a*a; }
31 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
32 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
33 template< class T > inline T lowbit(T x) { return x&-x; }
34 
35 inline int Read_int() {
36     char c;int ret = 0, sgn = 1;
37     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
38     if (c == '-')sgn = -1; else ret = c - '0';
39     while ((c = getchar()) >= '0'&& c <= '9')ret = ret * 10 + (c - '0');
40     return sgn*ret;
41 }
42 inline LL Read_LL() {
43     char c;LL ret = 0, sgn = 1;
44     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
45     if (c == '-')sgn = -1; else ret = c - '0';
46     while ((c = getchar()) >= '0'&&c <= '9')ret = ret * 10 + (c - '0');
47     return sgn*ret;
48 }
49 ///************************************START**************************************///
50 
51 int sum[MAXN][MAXN];
52 int main() {
53     int n = Read_int(), r = Read_int();
54     REP(i, 1, n) {
55         int u = Read_int(), v = Read_int(), w = Read_int();
56         sum[u + 1][v + 1] += w;
57     }
58     REP(i, 1, 5001)REP(j, 1, 5001)sum[i][j] += sum[i-1][j];
59     REP(i, 1, 5001)REP(j, 1, 5001)sum[i][j] += sum[i][j - 1];
60     int ans = 0;
61     REP(i, r, 5001)REP(j, r, 5001)
62         ans = max(ans, sum[i][j] + sum[i - r][j - r] - sum[i][j - r] - sum[i - r][j]);
63     printf("%d\n", ans);
64     return 0;
65 }

POJ3263

题意:

给出n头牛的身高,和m对关系(a[i]与b[i]可以相互看见。即他们中间的牛都比他们矮)。已知最高的牛为第p头,身高为h。

求每头牛的身高最大可能是多少。

解法:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 
  6 #define L(x) (x<<1)
  7 #define R(x) (x<<1|1)
  8 #define MID(x,y) ((x+y)>>1)
  9 using namespace std;
 10 #define INF 0x3f3f3f3f
 11 #define N  1000005
 12 
 13 int n, i, h, m;
 14 int lle[N], rri[N], k;
 15 
 16 struct stud {
 17     int le, ri;
 18     int va;
 19 }f[N];
 20 
 21 void pushdown(int pos)
 22 {
 23 
 24     if (f[pos].va == 0) return;
 25     f[L(pos)].va += f[pos].va;
 26     f[R(pos)].va += f[pos].va;
 27     f[pos].va = 0;
 28 }
 29 
 30 void build(int pos, int le, int ri)
 31 {
 32     f[pos].le = le;
 33     f[pos].ri = ri;
 34     f[pos].va = 0;
 35     if (le == ri) return;
 36 
 37     int mid = MID(le, ri);
 38     build(L(pos), le, mid);
 39     build(R(pos), mid + 1, ri);
 40 }
 41 
 42 void update(int pos, int le, int ri)
 43 {
 44     if (f[pos].le == le&&f[pos].ri == ri)
 45     {
 46         f[pos].va++;
 47         return;
 48     }
 49     pushdown(pos);
 50 
 51     int mid = MID(f[pos].le, f[pos].ri);
 52 
 53     if (mid >= ri)
 54         update(L(pos), le, ri);
 55     else
 56         if (mid < le)
 57             update(R(pos), le, ri);
 58         else
 59         {
 60             update(L(pos), le, mid);
 61             update(R(pos), mid + 1, ri);
 62         }
 63 
 64 }
 65 
 66 int query(int pos, int le)
 67 {
 68     if (f[pos].le == le&&f[pos].ri == le)
 69     {
 70         return h - f[pos].va;
 71     }
 72     pushdown(pos);
 73     int mid = MID(f[pos].le, f[pos].ri);
 74 
 75     if (mid >= le)
 76         return query(L(pos), le);
 77     else
 78         return query(R(pos), le);
 79 }
 80 
 81 int main()
 82 {
 83     int i, j;
 84     while (~scanf("%d%d%d%d", &n, &i, &h, &m))
 85     {
 86         build(1, 1, n);
 87         k = 0;
 88         lle[0] = rri[0] = 0;
 89         int le, ri;
 90         while (m--)
 91         {
 92             scanf("%d%d", &le, &ri);
 93             if (le > ri) { i = le; le = ri; ri = i; }
 94             if (le + 1 == ri) continue;
 95             for (i = 0; i < k; i++)
 96                 if (lle[i] == le&&rri[i] == ri)
 97                 {
 98                     i = -1;
 99                     break;
100                 }
101             if (i == -1) continue;
102             lle[k] = le;
103             rri[k++] = ri;
104             update(1, le + 1, ri - 1);
105         }
106 
107         for (i = 1; i <= n; i++)
108         {
109             printf("%d\n", query(1, i));
110         }
111 
112     }
113     return 0;
114 }

POJ1845  Sumdiv

题意:

求A^B的所有约数(即因子)之和,并对其取模 9901再输出。

解法:

这道题主要有两个可以学习借鉴的地方,第一个是数学思想的应用,第二个就是等比数列求和;

这里的等比数列求和除了用它的递归写法,还可以用乘法逆元;

分解质因数后就是一个等比数列的求和了

  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <vector>
 15 #include <queue>
 16 #include <deque>
 17 #include <utility>
 18 #include <bitset>
 19 #include <functional>
 20 using namespace std;
 21 
 22 const double EPS = 1e-9;
 23 const int INF = 2147483647;
 24 const int LLINF = 9223372036854775807;
 25 const double PI = acos(-1.0);
 26 
 27 #define     READ(f)       freopen(f, "r", stdin)
 28 #define     WRITE(f)      freopen(f, "w", stdout)
 29 #define     MP(x, y)      make_pair(x, y)
 30 #define     PB(x)         push_back(x)
 31 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
 32 #define     PER(i, a, b)  for(int i = (a); i < (b); i--)
 33 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((LL)9901)
 44 #define     MAXN          10000+5
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int Read_int() {
 53     char c;int ret = 0, sgn = 1;
 54     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
 55     if (c == '-')sgn = -1; else ret = c - '0';
 56     while ((c = getchar()) >= '0'&& c <= '9')ret = ret * 10 + (c - '0');
 57     return sgn*ret;
 58 }
 59 inline LL Read_LL() {
 60     char c;LL ret = 0, sgn = 1;
 61     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
 62     if (c == '-')sgn = -1; else ret = c - '0';
 63     while ((c = getchar()) >= '0'&&c <= '9')ret = ret * 10 + (c - '0');
 64     return sgn*ret;
 65 }
 66 ///************************************START**************************************///
 67 
 68 LL a, b;
 69 LL fac[MAXN], frq[MAXN];
 70 LL poww(LL x, LL n)
 71 {
 72     LL res = 1;
 73     while (n > 0)
 74     {
 75         if (n % 2 == 1)
 76         {
 77             res = res*x;
 78             res = res%MOD;
 79         }
 80         x = x*x;
 81         x = x%MOD;
 82         n >>= 1;
 83     }
 84     return res;
 85 }
 86 
 87 LL work_quality_factor(LL n, LL quality_fac[], LL frequency[])
 88 {//n是待分解的数,quality_fac[]会存放它包含的质因子,而frequency[]存放对应次数
 89  //如q_f[k]=7,fre[k]=2就表示质因数分解后里面包含有7,且次数是2
 90  //函数返回有几种质因子,比如分解了25就返回1,分解28返回2
 91     LL res, temp, i;
 92     res = 0;
 93     temp = n;
 94     for (i = 2; i*i <= temp; i++)
 95         if (temp%i == 0){
 96             quality_fac[res] = i;
 97             frequency[res] = 0;
 98             while (temp%i == 0){
 99                 temp = temp / i;
100                 frequency[res]++;
101             }
102             res++;
103         }
104     if (temp > 1){
105         quality_fac[res] = temp;
106         frequency[res++] = 1;
107     }
108     return res;
109 }
110 
111 LL cal_sum(LL p, LL c) {
112     if (c == 0)return 1;
113     if (c & 1) return ((1 + poww(p, (c + 1) / 2))*cal_sum(p, (c - 1) / 2)) % MOD;
114     else return ((1 + poww(p, c / 2))*cal_sum(p, c / 2 - 1) + poww(p, c)) % MOD;
115 }
116 
117 int main() {
118     while (cin >> a >> b) {
119         if (a <= 1 || b == 0) { cout << 1 << endl; continue; }
120         int num = work_quality_factor(a, fac, frq);
121         LL ans = 1;
122         REP(i, 0, num) ans = (ans*(cal_sum(fac[i], b*frq[i]) % MOD) % MOD);
123         cout << ans << endl;
124     }
125     return 0;
126 }

POJ2018 Best Cow Fences

题意:

给定一个长度为N的数组,求其中长度大于等于K的连续的一段,使其算数平均值最大。输出最大平均值*1000取整的结果。

解法:

二分答案,判定“是否存在一个长度不小于L的子段,平均数不小于二分的值”;

如果把数列中的每个数都减去二分的值,就转换为判定“是否存在一个长度不小于L的子段,子段和非负”;

子段和可以转换为前缀和相减的形式,即设sum[i],表示A1~Ai的和, 则有:max(A[j+1]+A[j+2]+...+A[i])=max(sum[i]-min(sum[j]))

 1 #pragma GCC optimize(3)
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cctype>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <cmath>
 8 #include <string>
 9 #include <cstring>
10 #include <sstream>
11 #include <stack>
12 #include <set>
13 #include <map>
14 #include <vector>
15 #include <queue>
16 #include <deque>
17 #include <utility>
18 #include <bitset>
19 #include <functional>
20 using namespace std;
21 
22 const double EPS = 1e-5;
23 const int INF = 2147483647;
24 const int LLINF = 9223372036854775807;
25 const double PI = acos(-1.0);
26 
27 #define     READ(f)       freopen(f, "r", stdin)
28 #define     WRITE(f)      freopen(f, "w", stdout)
29 #define     MP(x, y)      make_pair(x, y)
30 #define     PB(x)         push_back(x)
31 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
32 #define     PER(i, a, b)  for(int i = (a); i < (b); i--)
33 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
34 #define     SET(a)        memset(a,-1,sizeof(a))
35 #define     CLR(a)        memset(a,0,sizeof(a));
36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
37 #define     ALL(x)        begin(x),end(x)
38 #define     LL            long long
39 #define     Lson          (index * 2)
40 #define     Rson          (index * 2 + 1)
41 #define     pii           pair< int, int >
42 #define     pll           pair< LL, LL >
43 #define     MOD           ((LL)1000000007)
44 #define     MAXN          100000+5
45 
46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
47 template< class T > inline T sqr(T a) { return a*a; }
48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
50 template< class T > inline T lowbit(T x) { return (x&-x); }
51 
52 inline int Read_int() {
53     char c;int ret = 0, sgn = 1;
54     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
55     if (c == '-')sgn = -1; else ret = c - '0';
56     while ((c = getchar()) >= '0'&& c <= '9')ret = ret * 10 + (c - '0');
57     return sgn*ret;
58 }
59 inline LL Read_LL() {
60     char c;LL ret = 0, sgn = 1;
61     do { c = getchar(); } while ((c<'0' || c>'9') && c != '-');
62     if (c == '-')sgn = -1; else ret = c - '0';
63     while ((c = getchar()) >= '0'&&c <= '9')ret = ret * 10 + (c - '0');
64     return sgn*ret;
65 }
66 ///************************************START**************************************///
67 
68 double a[MAXN], b[MAXN], sum[MAXN];
69 int main() {
70     int n = Read_int(), L = Read_int();
71     REP(i, 1, n+1)scanf("%lf", &a[i]);
72     double l = 1e-6, r = 1e6;
73     while (r - l > EPS) {
74         double mid = (l + r) / 2;
75         REP(i, 1, n + 1) {
76             b[i] = a[i] - mid;
77             sum[i] = sum[i - 1] + b[i];
78         }
79         double ans = -1e10;
80         double min_val = 1e10;
81         REP(i, L, n + 1) {
82             min_val = min(min_val, sum[i - L]);
83             ans = max(ans, sum[i] - min_val);
84         }
85         if (ans >= 0)l = mid;
86         else r = mid;
87     }
88     cout << int(r * 1000) << endl;
89     return 0;
90 }

CF670C

题意:

N个科学家要去看电影,每个科学家只懂得一种语言。电影有两个语言:原声和字幕 

选择一个片子使得能听懂原声的科学家数最大化,如果有多种可能,选取字幕最大化的那一个片子。输出片子的序号

解法:

离散化的基本应用;

注意因为语言的范围非常大,所以我们可以用map直接进行离散化

 1 #pragma GCC optimize(3)
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 const double EPS = 1e-9;
 6 const int INF = 2147483647;
 7 const int LLINF = 9223372036854775807;
 8 const double PI = acos(-1.0);
 9 
10 #define     READ(f)       freopen(f, "r", stdin)
11 #define     WRITE(f)      freopen(f, "w", stdout)
12 #define     MP(x, y)      make_pair(x, y)
13 #define     PB(x)         push_back(x)
14 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
15 #define     PER(i, a, b)  for(int i = (a); i < (b); i--)
16 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
17 #define     SET(a)        memset(a,-1,sizeof(a))
18 #define     CLR(a)        memset(a,0,sizeof(a));
19 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
20 #define     ALL(x)        begin(x),end(x)
21 #define     LL            long long
22 #define     Lson          (index * 2)
23 #define     Rson          (index * 2 + 1)
24 #define     pii           pair< int, int >
25 #define     pll           pair< LL, LL >
26 #define     MOD           ((LL)1000000007)
27 #define     MAXN          2000000
28 
29 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
30 template< class T > inline T sqr(T a) { return a*a; }
31 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
32 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
33 template< class T > inline T lowbit(T x) { return x&-x; }
34 
35 ///************************************START**************************************///
36 
37 struct mov {
38     int au, ti, id;
39     bool operator < (const mov&rhs) const {
40         return au > rhs.au || (au == rhs.au&&ti > rhs.ti);
41     }
42 }M[MAXN];
43 map<int, int>lan;
44 int a[MAXN];
45 mov Mov[MAXN];
46 
47 int main() {
48     int n; scanf("%d", &n);
49     REP(i, 0, n) scanf("%d", &a[i]), lan[a[i]]++;
50     int m; scanf("%d", &m);
51     REP(i, 0, m) scanf("%d", &Mov[i].au);
52     REP(i, 0, m) scanf("%d", &Mov[i].ti);
53     REP(i, 0, m) {
54         M[i].au = lan[Mov[i].au];
55         M[i].ti = lan[Mov[i].ti];
56         M[i].id = i + 1;
57     }
58     sort(M, M + m);
59     printf("%d\n", M[0].id);
60     return 0;
61 }

POJ3784(动态维护中位数)

题意:

1000个case

每个case  

输入若干个数,对第k个输入,如果k为奇数,则输出前k个数的中位数

解法:

维护对顶堆,大根堆储存的是前1~M个元素,小根堆储存的是后M+1~M个元素;

中位数就是小根堆的堆顶;

每次读入元素与中位数比较,大于就插到小根堆,小于就插入到大根堆,之后根据性质,通过两个堆里面的元素数量进行维护即可

 1 #pragma GCC optimize(3)
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cctype>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <cmath>
 8 #include <string>
 9 #include <cstring>
10 #include <sstream>
11 #include <stack>
12 #include <set>
13 #include <map>
14 #include <vector>
15 #include <queue>
16 #include <deque>
17 #include <utility>
18 #include <bitset>
19 #include <functional>
20 using namespace std;
21 
22 const double EPS = 1e-9;
23 const int INF = 2147483647;
24 const int LLINF = 9223372036854775807;
25 const double PI = acos(-1.0);
26 
27 #define     READ(f)       freopen(f, "r", stdin)
28 #define     WRITE(f)      freopen(f, "w", stdout)
29 #define     MP(x, y)      make_pair(x, y)
30 #define     PB(x)         push_back(x)
31 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
32 #define     PER(i, a, b)  for(int i = (a); i < (b); i--)
33 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
34 #define     SET(a)        memset(a,-1,sizeof(a))
35 #define     CLR(a)        memset(a,0,sizeof(a));
36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
37 #define     ALL(x)        begin(x),end(x)
38 #define     LL            long long
39 #define     Lson          (index * 2)
40 #define     Rson          (index * 2 + 1)
41 #define     pii           pair< int, int >
42 #define     pll           pair< LL, LL >
43 #define     MOD           ((LL)1000000007)
44 #define     MAXN          5000+5
45 
46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
47 template< class T > inline T sqr(T a) { return a*a; }
48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
50 template< class T > inline T lowbit(T x) { return x&-x; }
51 
52 ///************************************START**************************************///
53 priority_queue <int, vector<int>, less<int> > p;//从大到小(大根堆)
54 priority_queue <int, vector<int>, greater<int> > q;//从小到大 (小根堆)
55 vector<int>ans;
56 int main() {
57     int T; scanf("%d", &T);
58     int kase = 1;
59     while (T--) {
60         int useless; scanf("%d", &useless);
61         int n; scanf("%d", &n);
62         int k = 0;
63         ans.clear();
64         while (!q.empty())q.pop();
65         while (!p.empty())p.pop();
66         while (++k <= n) {
67             int o; scanf("%d", &o);
68             if (q.empty()) {
69                 q.push(o);
70                 ans.push_back(o);
71                 continue;
72             }
73             if (q.top() > o)p.push(o);
74             else q.push(o);
75             if (p.size() > k / 2)
76                 q.push(p.top()), p.pop();
77             else if (q.size() >= k - k / 2 + 1)
78                 p.push(q.top()), q.pop();
79 
80             if (k & 1)ans.push_back(q.top());
81         }
82 
83         printf("%d %d\n", kase++, ans.size());
84         for (int i = 0; i < ans.size(); i++) { 
85             if (i > 0 && i % 10 == 0) putchar('\n');           
86             if (i % 10) putchar(' ');         
87             printf("%d", ans[i]); 
88         }cout << endl;
89     }
90     return 0;
91 }

POJ2299(归并排序找逆序对数)

题意:

本题要求对于给定的无序数组,求出经过最少多少次相邻元素的交换之后,可以使数组从小到大有序。

解法:

归并排序统计逆序对数,在合并的时候统计逆序对数

 1 #pragma GCC optimize(3)
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cctype>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <cmath>
 8 #include <string>
 9 #include <cstring>
10 #include <sstream>
11 #include <stack>
12 #include <set>
13 #include <map>
14 #include <time.h>
15 #include <vector>
16 #include <queue>
17 #include <deque>
18 #include <utility>
19 #include <bitset>
20 #include <functional>
21 using namespace std;
22 
23 const double EPS = 1e-9;
24 const int INF = 2147483647;
25 const int LLINF = 9223372036854775807;
26 const double PI = acos(-1.0);
27 
28 #define     READ(f)       freopen(f, "r", stdin)
29 #define     WRITE(f)      freopen(f, "w", stdout)
30 #define     MP(x, y)      make_pair(x, y)
31 #define     PB(x)         push_back(x)
32 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
33 #define     PER(i, a, b)  for(int i = (a); i < (b); i--)
34 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
35 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
36 #define     SET(a)        memset(a,-1,sizeof(a))
37 #define     CLR(a)        memset(a,0,sizeof(a));
38 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
39 #define     ALL(x)        begin(x),end(x)
40 #define     LL            long long
41 #define     Lson          (index * 2)
42 #define     Rson          (index * 2 + 1)
43 #define     pii           pair< int, int >
44 #define     pll           pair< LL, LL >
45 #define     MOD           ((LL)1000000007)
46 #define     MAXN          500000+5
47 
48 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
49 template< class T > inline T sqr(T a) { return a*a; }
50 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
51 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
52 template< class T > inline T lowbit(T x) { return x&-x; }
53 
54 ///************************************START**************************************///
55 LL a[MAXN], b[MAXN];
56 LL cnt;
57 //a为待排序数组,b为最终数组,cnt为逆序对数
58 void merge(int l, int mid, int r) {
59     int i = l, j = mid + 1;
60     for (int k = l; k <= r; k++) {
61         if (j > r || i <= mid&&a[i] < a[j])b[k] = a[i++];
62         else b[k] = a[j++], cnt += mid - i + 1;
63     }
64     for (int k = l; k <= r; k++)a[k] = b[k];
65 }
66 void mergesort(int l, int r) {
67     if (l < r) {
68         int mid = (l + r) / 2;
69         mergesort(l, mid);
70         mergesort(mid + 1, r);
71         merge(l, mid, r);//在合并的同时统计逆序对数
72     }
73 }
74 int main() {
75     int n;
76     while (scanf("%d", &n) && n) {
77         CLR(a); CLR(b);
78         cnt = 0;
79         REP(i, 0, n)scanf("%lld", &a[i]);
80         mergesort(0, n - 1);
81         printf("%lld\n", cnt);
82     }
83     return 0;
84 }

POJ3614(贪心)

题意:

有C头牛和L瓶防晒霜,每头牛有一个最小SPF和最大SPF,每瓶防嗮霜能使一头牛维持在特定的SPF,问最多有几头牛能使用防晒霜

解法:

优先按上界小的排,之后再按下界小的排;

多体会一下这样子的贪心策略

 1 #pragma GCC optimize(3)
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cctype>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <cmath>
 8 #include <string>
 9 #include <cstring>
10 #include <sstream>
11 #include <stack>
12 #include <set>
13 #include <map>
14 #include <time.h>
15 #include <vector>
16 #include <queue>
17 #include <deque>
18 #include <utility>
19 #include <bitset>
20 #include <functional>
21 using namespace std;
22 
23 const double EPS = 1e-9;
24 const int INF = 2147483647;
25 const int LLINF = 9223372036854775807;
26 const double PI = acos(-1.0);
27 
28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
32 #define     MP(x, y)      make_pair(x, y)
33 #define     PB(x)         push_back(x)
34 #define     SET(a)        memset(a,-1,sizeof(a))
35 #define     CLR(a)        memset(a,0,sizeof(a));
36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
37 #define     ALL(x)        begin(x),end(x)
38 #define     LL            long long
39 #define     Lson          (index * 2)
40 #define     Rson          (index * 2 + 1)
41 #define     pii           pair< int, int >
42 #define     pll           pair< LL, LL >
43 #define     MOD           ((int)1000000007)
44 #define     MAXN          3000
45 
46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
47 template< class T > inline T sqr(T a) { return a*a; }
48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
50 template< class T > inline T lowbit(T x) { return x&-x; }
51 
52 inline int READ() {
53     char ch;
54     while ((ch = getchar()) < 48 || 57 < ch);
55     int ans = ch - 48;
56     while (48 <= (ch = getchar()) && ch <= 57) 
57         ans = (ans << 3) + (ans << 1) + ch - 48;
58     return ans;
59 }
60 ///************************************START**************************************///
61 struct COW {
62     int l, r;
63     bool operator < (const COW &rhs) const {
64         //优先按上界小的排,之后再按下界小的排
65         return r == rhs.r ? l < rhs.l : r < rhs.r;
66     }
67 }cow[MAXN];
68 int sun[MAXN];
69 
70 int main() {
71     int C = READ(), L = READ();
72     REP(i, 0, C) {
73         cow[i].l = READ();
74         cow[i].r = READ();
75     }    
76     REP(i, 0, L) {
77         int id = READ();
78         sun[id]+= READ();
79     }
80     sort(cow, cow + C);
81 
82     int cnt = 0;
83     REP(i, 0, C)REP(j, cow[i].l, cow[i].r + 1) {
84         if (sun[j]) {
85             sun[j]--;
86             cnt++;
87             break;
88         }
89     }
90     cout << cnt << endl;
91     return 0;
92 }

POJ3190(贪心)

题意:

一群很有个性的奶牛,只在固定的时间产奶,每头牛需要用一个挤奶机器,问为满足所有牛产奶,最少需要多少个挤奶机器,并按照奶牛给出的顺序来输出该奶牛挤奶机器的编号。

解法:

按照开始吃草的顺序把牛排队,之后对于每个牛, 如果它要等,就直接给他开一个新的,否则就把它排到那个最先结束的牛的后面;

  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <time.h>
 15 #include <vector>
 16 #include <queue>
 17 #include <deque>
 18 #include <utility>
 19 #include <bitset>
 20 #include <functional>
 21 using namespace std;
 22 
 23 const double EPS = 1e-9;
 24 const int INF = 2147483647;
 25 const int LLINF = 9223372036854775807;
 26 const double PI = acos(-1.0);
 27 
 28 #define     REP(i, a, b)  for(int i = (a); i <= (b); i++)
 29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
 30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
 32 #define     MP(x, y)      make_pair(x, y)
 33 #define     PB(x)         push_back(x)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((int)1000000007)
 44 #define     MAXN          50000+10
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int READ() {
 53     char ch;
 54     while ((ch = getchar()) < 48 || 57 < ch);
 55     int ans = ch - 48;
 56     while (48 <= (ch = getchar()) && ch <= 57) 
 57         ans = (ans << 3) + (ans << 1) + ch - 48;
 58     return ans;
 59 }
 60 ///************************************START**************************************///
 61 
 62 struct COW{ 
 63     int l, r, id;
 64     bool operator < (const COW & rhs)const {
 65         return l == rhs.l ? r < rhs.r : l < rhs.l;
 66     }
 67 }cow[MAXN];
 68 struct BET { 
 69     int id,r; 
 70     bool operator < (const BET & rhs) const {
 71         return r > rhs.r;
 72     }
 73 };
 74 priority_queue<BET>q;
 75 int ans[MAXN];
 76 int main() {
 77     CLR(ans);
 78     int n = READ();
 79     REP(i, 1, n) {
 80         cow[i].l = READ();
 81         cow[i].r = READ();
 82         cow[i].id = i;
 83     }
 84     sort(cow + 1, cow + n + 1);
 85 
 86     int cnt = 0;
 87     REP(i, 1, n) {
 88         if (q.empty() || q.top().r >= cow[i].l) {
 89             ans[cow[i].id] = ++cnt;
 90             q.push(BET{ cnt,cow[i].r });
 91         }
 92         else {
 93             ans[cow[i].id] = q.top().id;
 94             q.pop();
 95             q.push(BET{ ans[cow[i].id],cow[i].r });
 96         }
 97     }
 98     printf("%d\n", cnt);
 99     REP(i, 1, n)printf("%d\n", ans[i]);
100     return 0;
101 }

POJ1328(贪心)

题意:

地图的x轴的上方为海,下方为陆地,海中有n个小岛,坐标为(isl[i].x,isl[i].y)。

有一种雷达,能探测到的范围为以d为半径的圆。

问海岸线上至少造多少雷达可以把所有的小岛都包含在内。注意雷达是建在海岸线上的,也就是x轴上的。

解法:

贪心,首先处理出每个目标可以被覆盖的左右区间,之后每个基地都安排在这个区间的最右边,

更新的时候注意更新为这个区间的最右边和当前位置的最小值

  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <time.h>
 15 #include <vector>
 16 #include <queue>
 17 #include <deque>
 18 #include <utility>
 19 #include <bitset>
 20 #include <functional>
 21 using namespace std;
 22 
 23 const double EPS = 1e-9;
 24 const int INF = 2147483647;
 25 const int LLINF = 9223372036854775807;
 26 const double PI = acos(-1.0);
 27 
 28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
 29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
 30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
 32 #define     MP(x, y)      make_pair(x, y)
 33 #define     PB(x)         push_back(x)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((int)1000000007)
 44 #define     MAXN          1000+5
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int READ() {
 53     char ch;
 54     while ((ch = getchar()) < 48 || 57 < ch);
 55     int ans = ch - 48;
 56     while (48 <= (ch = getchar()) && ch <= 57) 
 57         ans = (ans << 3) + (ans << 1) + ch - 48;
 58     return ans;
 59 }
 60 ///************************************START**************************************///
 61 struct Point { 
 62     double x, y;
 63     double l, r;
 64     bool operator < (const Point &rhs) const {
 65         return l == rhs.l ? r < rhs.r : l < rhs.l;
 66     }
 67 }p[MAXN];
 68 
 69 int main() {
 70     int n, kase = 0;
 71     double d;
 72     while (scanf("%d%lf", &n, &d) != EOF && (n || d)) {
 73         int flag = 0;
 74         REP(i, 0, n) {
 75             scanf("%lf%lf", &p[i].x, &p[i].y);
 76             if (p[i].y > d)flag = 1;
 77             p[i].l = 1.0*p[i].x - sqrt(sqr(d) - sqr(p[i].y));
 78             p[i].r = 1.0*p[i].x + sqrt(sqr(d) - sqr(p[i].y));
 79         }
 80         printf("Case %d: ", ++kase);
 81         if (flag) {
 82             printf("-1\n");
 83             continue;
 84         }
 85         sort(p, p + n);
 86         int cnt = 1;
 87         double pos = p[0].r;
 88         REP(i, 1, n) {
 89             if (p[i].l > pos) {
 90                 cnt++;
 91                 pos = p[i].r;
 92             }
 93             else {
 94                 pos = min(p[i].r, pos);
 95             }
 96         }
 97         printf("%d\n", cnt);
 98     }
 99     return 0;
100 }

POJ2965(枚举/位运算)

题意:

就是把题目中给出的状态图,全部翻转成
----
----
----
----状态
翻转: 每次翻转一个,那么它所在的行和列都要翻转
问最小翻转次数,同时输出翻转路径.
解法:
简单的深搜,还是要多写这样的题目加强训练啊
  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <time.h>
 15 #include <vector>
 16 #include <queue>
 17 #include <deque>
 18 #include <utility>
 19 #include <bitset>
 20 #include <functional>
 21 using namespace std;
 22 
 23 const double EPS = 1e-9;
 24 const int INF = 2147483647;
 25 const int LLINF = 9223372036854775807;
 26 const double PI = acos(-1.0);
 27 
 28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
 29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
 30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
 32 #define     MP(x, y)      make_pair(x, y)
 33 #define     PB(x)         push_back(x)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((int)1000000007)
 44 #define     MAXN          20
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int READ() {
 53     char ch;
 54     while ((ch = getchar()) < 48 || 57 < ch);
 55     int ans = ch - 48;
 56     while (48 <= (ch = getchar()) && ch <= 57) 
 57         ans = (ans << 3) + (ans << 1) + ch - 48;
 58     return ans;
 59 }
 60 ///************************************START**************************************///
 61 
 62 char s[5][5];
 63 int mp[5][5], ansx[MAXN], ansy[MAXN], x[MAXN], y[MAXN];
 64 int n = 4, ans = INF;
 65 int check() {
 66     REP(i, 0, n)REP(j, 0, n) {
 67         if (mp[i][j] == 0)return 0;
 68     }
 69     return 1;
 70 }
 71 
 72 void flip(int s) {
 73     int x = s / 4;
 74     int y = s % 4;
 75     REP(i, 0, n) {
 76         mp[i][y] = !mp[i][y];
 77         mp[x][i] = !mp[x][i];
 78     }
 79     mp[x][y] = !mp[x][y];
 80 }
 81 
 82 void solve(int s,int b) {
 83     if (check()) {
 84         if (ans > b) {
 85             ans = b;
 86             REP(i, 1, ans + 1) {
 87                 ansx[i] = x[i];
 88                 ansy[i] = y[i];
 89             }
 90         }
 91         return;
 92     }
 93     if (s >= 16)return;
 94     solve(s + 1, b);
 95     
 96     flip(s);
 97     x[b + 1] = s / 4 + 1;
 98     y[b + 1] = s % 4 + 1;
 99     solve(s + 1, b + 1);
100     flip(s);
101 }
102 
103 int main() {
104     REP(i, 0, n) scanf("%s", s[i]);
105     REP(i, 0, n)REP(j, 0, n) {
106         if (s[i][j] == '-')mp[i][j] = 1;//open
107         else mp[i][j] = 0;
108     }
109     solve(0, 0);
110     printf("%d\n", ans);
111     REP(i, 1, ans+1) {
112         printf("%d %d\n", ansx[i], ansy[i]);
113     }
114     return 0;
115 }

POJ2083(分型图的画法)

题意:

画一个深度为k的分型图

解法:

不要方,直接输出即可

  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <time.h>
 15 #include <vector>
 16 #include <queue>
 17 #include <deque>
 18 #include <utility>
 19 #include <bitset>
 20 #include <functional>
 21 using namespace std;
 22 
 23 const double EPS = 1e-9;
 24 const int INF = 2147483647;
 25 const int LLINF = 9223372036854775807;
 26 const double PI = acos(-1.0);
 27 
 28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
 29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
 30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
 32 #define     MP(x, y)      make_pair(x, y)
 33 #define     PB(x)         push_back(x)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((int)1000000007)
 44 #define     MAXN          730
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int READ() {
 53     char ch;
 54     while ((ch = getchar()) < 48 || 57 < ch);
 55     int ans = ch - 48;
 56     while (48 <= (ch = getchar()) && ch <= 57) 
 57         ans = (ans << 3) + (ans << 1) + ch - 48;
 58     return ans;
 59 }
 60 ///************************************START**************************************///
 61 int mp[MAXN][MAXN];
 62 
 63 void generate(int deep) {
 64     int step = pow(3, deep - 1);
 65     int tot = pow(3, deep);
 66     //右上
 67     REP(i, 0, step)REP(j, tot-step, tot) {
 68         int dis = tot - step;
 69         mp[i][j] = mp[i][j - dis];
 70     }
 71     //左下
 72     REP(i, tot - step, tot)REP(j, 0, step) {
 73         int dis = tot - step;
 74         mp[i][j] = mp[i-dis][j];
 75     }
 76     //右下
 77     REP(i, tot - step, tot)REP(j, tot - step, tot) {
 78         int dis = tot - step;
 79         mp[i][j] = mp[i - dis][j - dis];
 80     }
 81     //中间
 82     REP(i, step, tot - step)REP(j, step, tot - step) {
 83         int dis = step;
 84         mp[i][j] = mp[i - dis][j - dis];
 85     }
 86     return;
 87 }
 88 
 89 int main() {
 90     int n; mp[0][0] = 1;
 91     REP(i,1,7)    generate(i);
 92     //NEED_CLOCK;
 93     while (scanf("%d",&n) && n != -1) {
 94         int tot = pow(3, n - 1);
 95         REP(i, 0, tot) {
 96             REP(j, 0, tot) {
 97                 if (mp[i][j] == 1)putchar('X');
 98                 else putchar(' ');
 99             }
100             puts("");
101         }
102         puts("-");
103     }
104     return 0;
105 }

POJ3714(分治/平面最近点对)

题意:

有两个点集,求集合不同的点的最小距离

解法:

板子题

#pragma GCC optimize(3)
#include <cstdio>
#include <iostream>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <sstream>
#include <stack>
#include <set>
#include <map>
#include <time.h>
#include <vector>
#include <queue>
#include <deque>
#include <utility>
#include <bitset>
#include <functional>
using namespace std;

const double EPS = 1e-9;
const double INF = 1e50;
const int LLINF = 9223372036854775807;
const double PI = acos(-1.0);

#define     REP(i, a, b)  for(int i = (a); i < (b); i++)
#define     PER(i, a, b)  for(int i = (a); i > (b); i--)
#define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
#define     MP(x, y)      make_pair(x, y)
#define     PB(x)         push_back(x)
#define     SET(a)        memset(a,-1,sizeof(a))
#define     CLR(a)        memset(a,0,sizeof(a));
#define     MEM(a,x)      memset(a,x,sizeof(a)) 
#define     ALL(x)        begin(x),end(x)
#define     LL            long long
#define     Lson          (index * 2)
#define     Rson          (index * 2 + 1)
#define     pii           pair< int, int >
#define     pll           pair< LL, LL >
#define     MOD           ((int)1000000007)
#define     MAXN          (200000+5)

template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
template< class T > inline T sqr(T a) { return a*a; }
template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
template< class T > inline T lowbit(T x) { return x&-x; }

inline int READ() {
    char ch;
    while ((ch = getchar()) < 48 || 57 < ch);
    int ans = ch - 48;
    while (48 <= (ch = getchar()) && ch <= 57)
        ans = (ans << 3) + (ans << 1) + ch - 48;
    return ans;
}
///************************************START**************************************///
int n;
int ans[MAXN];
struct POINT {
    double x, y;
    int flag;
}p[MAXN];
bool cmpx(POINT a, POINT b) {return a.x != b.x ? a.x < b.x : a.y < b.y;}
bool cmpy(int a, int b) {return p[a].y < p[b].y;}

double dis(POINT a, POINT b) {
    if (a.flag == b.flag)return INF;
    else return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}

double divide(int left, int right) {
    double d = INF;
    if (left == right)return d;
    if (left + 1 == right)return dis(p[left], p[right]);
    int mid = (left + right) >> 1;
    double d1 = divide(left, mid);
    double d2 = divide(mid + 1, right);
    d = min(d1, d2);
    int k = 0;
    for (int i = left; i <= right; i++) {
        if (abs(p[mid].x - p[i].x) <= d)
            ans[k++] = i;
    }
    sort(ans, ans + k, cmpy);
    for (int i = 0; i < k - 1; i++) {
        for (int j = i + 1; j < k; j++) {
            if (p[ans[j]].y - p[ans[i]].y >= d) break;
            d = min(d, dis(p[ans[i]], p[ans[j]]));
        }
    }
    return d;
}

int main() {
    int T = READ();
    while (T--) {
        n = READ();
        REP(i, 0, n) {
            scanf("%lf%lf", &p[i].x, &p[i].y);
            p[i].flag = 1;
        }
        REP(i, n, 2 * n) {
            scanf("%lf%lf", &p[i].x, &p[i].y);
            p[i].flag = 2;
        }
        n *= 2;
        sort(p, p + n, cmpx);
        printf("%.3f\n", divide(0, n - 1));
    }
    return 0;
}

BZOJ1045(排序/中位数/环形均分纸牌)

题意:

有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。

解法:

维护前缀和即可

 1 #pragma GCC optimize(3)
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 const double EPS = 1e-9;
 6 const int INF = 2147483647;
 7 const int LLINF = 9223372036854775807;
 8 const double PI = acos(-1.0);
 9 
10 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
11 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
12 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
13 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
14 #define     MP(x, y)      make_pair(x, y)
15 #define     PB(x)         push_back(x)
16 #define     SET(a)        memset(a,-1,sizeof(a))
17 #define     CLR(a)        memset(a,0,sizeof(a));
18 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
19 #define     ALL(x)        begin(x),end(x)
20 #define     LL            long long
21 #define     Lson          (index * 2)
22 #define     Rson          (index * 2 + 1)
23 #define     pii           pair< int, int >
24 #define     pll           pair< LL, LL >
25 #define     MOD           ((int)1000000007)
26 #define     MAXN          1000000+5
27 
28 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
29 template< class T > inline T sqr(T a) { return a*a; }
30 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
31 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
32 template< class T > inline T lowbit(T x) { return x&-x; }
33 
34 inline int READ() {
35     char ch;
36     while ((ch = getchar()) < 48 || 57 < ch);
37     int ans = ch - 48;
38     while (48 <= (ch = getchar()) && ch <= 57) 
39         ans = (ans << 3) + (ans << 1) + ch - 48;
40     return ans;
41 }
42 ///************************************START**************************************///
43 LL a[MAXN], s[MAXN];
44 
45 int main() {
46     int n = READ();
47     LL sum = 0;
48     for (int i = 1; i <= n; i++) {
49         a[i] = READ();
50         sum += a[i];
51     }
52     sum /= n;
53     for (int i = 1; i <= n; i++) {
54         s[i] += s[i - 1] + a[i] - sum;
55     }
56     sort(s + 1, s + 1 + n);
57     LL k;
58     if (n & 1) k = s[(n + 1) / 2];
59     else k = (s[n / 2] + s[n / 2 + 1])/2;
60     LL ans = 0;
61     REP(i, 1, n + 1) {
62         ans += abs(s[i] - k);
63     }
64     printf("%lld\n", ans);
65     return 0;
66 }

POJ1050(二维最大子段和)

题意:

简单易懂,求一个最大为100*100矩阵中的子矩阵中元素之和的最大值

解法:

二维最大子段和;

枚举子段开始的行位置,先算出来一维子段和,然后一维一维的往上累加;

最大的那个就是我们要求的二位最大子段和。

 1 #pragma GCC optimize(3)
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <cctype>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <cmath>
 8 #include <string>
 9 #include <cstring>
10 #include <sstream>
11 #include <stack>
12 #include <set>
13 #include <map>
14 #include <time.h>
15 #include <vector>
16 #include <queue>
17 #include <deque>
18 #include <utility>
19 #include <bitset>
20 #include <functional>
21 using namespace std;
22 
23 const double EPS = 1e-9;
24 const int INF = 2147483647;
25 const int LLINF = 9223372036854775807;
26 const double PI = acos(-1.0);
27 
28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
32 #define     MP(x, y)      make_pair(x, y)
33 #define     PB(x)         push_back(x)
34 #define     SET(a)        memset(a,-1,sizeof(a))
35 #define     CLR(a)        memset(a,0,sizeof(a));
36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
37 #define     ALL(x)        begin(x),end(x)
38 #define     LL            long long
39 #define     Lson          (index * 2)
40 #define     Rson          (index * 2 + 1)
41 #define     pii           pair< int, int >
42 #define     pll           pair< LL, LL >
43 #define     MOD           ((int)1000000007)
44 #define     MAXN          101
45 
46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
47 template< class T > inline T sqr(T a) { return a*a; }
48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
50 template< class T > inline T lowbit(T x) { return x&-x; }
51 
52 inline int READ() {
53     char ch;
54     while ((ch = getchar()) < 48 || 57 < ch);
55     int ans = ch - 48;
56     while (48 <= (ch = getchar()) && ch <= 57) 
57         ans = (ans << 3) + (ans << 1) + ch - 48;
58     return ans;
59 }
60 ///************************************START**************************************///
61 int a[MAXN][MAXN];
62 int s[MAXN];
63 
64 //最大子段和
65 int MaxArray(int a[], int n){
66     int m = -INF;
67     int tmp = -1;
68     for (int i = 0; i < n; i++) {
69         if (tmp > 0) tmp += a[i];
70         else tmp = a[i];
71         if (tmp > m) m = tmp;
72     }
73     return m;
74 }
75 
76 int main() {
77     int n; scanf("%d", &n);
78     REP(i, 0, n)REP(j, 0, n)
79         scanf("%d", &a[i][j]);
80     int ans = -INF;
81     REP(i, 0, n) {
82         CLR(s);
83         REP(j, i, n) {
84             REP(k, 0, n) s[k] += a[j][k];
85             ans = max(ans, MaxArray(s, n));
86         }
87     }
88     printf("%d\n", ans);
89     return 0;
90 }

hdu4864(贪心)

题意:

有n个机器,m个任务。每个机器至多能完成一个任务。对于每个机器,有一个最大运行时间xi和等级yi,对于每个任务,也有一个运行时间xj和等级yj。只有当xi>=xj且yi>=yj的时候,机器i才能完成任务j,并获得500*xj+2*yj金钱。问最多能完成几个任务,当出现多种情况时,输出获得金钱最多的情况。
解法:

将任务已x从大到小排序(x相同时已y从大到小排序)。然后也用相同排序方法排序机器。开始遍历任务,找出所有xi(xi>=xj),从中选择yi最小的一个作为这个任务的运行机器。为什么这么贪心,因为若还存在任务(xk,yk)使得这个机器能被使用,但xj>=xk,所以获得金钱更多,优先选择j;若k不能使用这个机器,那么必定也就不存在其他机器能被使用,除非是新加入的机器,但新加入的必定不能完成任务j,所以完成任务保证了最多。

  1 #pragma GCC optimize(3)
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cctype>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <string>
  9 #include <cstring>
 10 #include <sstream>
 11 #include <stack>
 12 #include <set>
 13 #include <map>
 14 #include <time.h>
 15 #include <vector>
 16 #include <queue>
 17 #include <deque>
 18 #include <utility>
 19 #include <bitset>
 20 #include <functional>
 21 using namespace std;
 22 
 23 const double EPS = 1e-9;
 24 const int INF = 2147483647;
 25 const int LLINF = 9223372036854775807;
 26 const double PI = acos(-1.0);
 27 
 28 #define     REP(i, a, b)  for(int i = (a); i < (b); i++)
 29 #define     PER(i, a, b)  for(int i = (a); i > (b); i--)
 30 #define     FOREACH(i,t)  for(typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
 31 #define     NEED_CLOCK    printf("Time: %f\n",double(clock())/CLOCKS_PER_SEC)
 32 #define     MP(x, y)      make_pair(x, y)
 33 #define     PB(x)         push_back(x)
 34 #define     SET(a)        memset(a,-1,sizeof(a))
 35 #define     CLR(a)        memset(a,0,sizeof(a));
 36 #define     MEM(a,x)      memset(a,x,sizeof(a)) 
 37 #define     ALL(x)        begin(x),end(x)
 38 #define     LL            long long
 39 #define     Lson          (index * 2)
 40 #define     Rson          (index * 2 + 1)
 41 #define     pii           pair< int, int >
 42 #define     pll           pair< LL, LL >
 43 #define     MOD           ((int)1000000007)
 44 #define     MAXN          100000+5
 45 
 46 template< class T > inline T _abs(T a) { return a >= 0 ? a : -a; }
 47 template< class T > inline T sqr(T a) { return a*a; }
 48 template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % b)); }
 49 template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b))*(b)); }
 50 template< class T > inline T lowbit(T x) { return x&-x; }
 51 
 52 inline int READ() {
 53     char ch;
 54     while ((ch = getchar()) < 48 || 57 < ch);
 55     int ans = ch - 48;
 56     while (48 <= (ch = getchar()) && ch <= 57) 
 57         ans = (ans << 3) + (ans << 1) + ch - 48;
 58     return ans;
 59 }
 60 ///************************************START**************************************///
 61 struct TASK {
 62     int t, h;
 63     bool operator < (const TASK& rhs)const {
 64         return t == rhs.t ? h > rhs.h:t > rhs.t;
 65     }
 66 }task[MAXN];
 67 
 68 struct MACHINE {
 69     int t, h;
 70     bool operator < (const MACHINE& rhs)const {
 71         return t == rhs.t ? h > rhs.h:t > rhs.t;
 72     }
 73 }mach[MAXN];
 74 
 75 int vis[MAXN];
 76 
 77 int main() {
 78     int n, m;
 79     while (scanf("%d%d", &n, &m) == 2) {
 80         REP(i, 0, n)mach[i].t = READ(), mach[i].h = READ();
 81         REP(i, 0, m)task[i].t = READ(), task[i].h = READ();
 82         sort(mach, mach + n);
 83         sort(task, task + m);
 84 
 85         int cnt = 0;
 86         LL sum = 0;
 87         int j = 0;
 88         memset(vis, 0, sizeof(vis));
 89         REP(i, 0, m) {
 90             while (j < n&&mach[j].t >= task[i].t) {
 91                 vis[mach[j].h]++;
 92                 j++;
 93             }
 94             REP(k, task[i].h, 101) {
 95                 if (vis[k] > 0) {
 96                     cnt++;
 97                     sum += 500 * task[i].t + 2 * task[i].h;
 98                     vis[k]--;
 99                     break;
100                 }
101             }
102         }
103         cout << cnt << " " << sum << endl;
104     }
105     return 0;
106 }

 

posted @ 2018-10-27 17:29  romaLzhih  阅读(654)  评论(0编辑  收藏  举报