算法竞赛进阶指南第一章题解
例题: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 }