A:贪心,遍历每次维护一个最便宜的价格,假如当前价格不如此前价格,就用此前价格购买当前数量的肉,每次更新最便宜的价格。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef struct Node { 23 int a; 24 int p; 25 int day; 26 }Node; 27 const int maxn = 100010; 28 int n; 29 Node orz[maxn]; 30 31 32 int main() { 33 // freopen("in", "r", stdin); 34 while(~scanf("%d", &n)) { 35 int minn = 0x7f7f7f; 36 int midx; 37 int ans = 0; 38 for(int i = 1; i <= n; i++) { 39 scanf("%d %d", &orz[i].a, &orz[i].p); 40 if(minn > orz[i].p) { 41 minn = orz[i].p; 42 ans += minn * orz[i].a; 43 } 44 else { 45 ans += minn * orz[i].a; 46 } 47 } 48 cout << ans << endl; 49 } 50 return 0; 51 }
A
B:根据一个性质2^k=2*2^(k-1),每次计数不同幂的个数,假如有偶数个就向下一个数进位并划归为下一个数的个数(k/2个),直到k是奇数的时候,这时候举一次再更新。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef long long ll; 23 const int maxn = 1100010; 24 int n; 25 ll dp[maxn]; 26 27 int main() { 28 // freopen("in", "r", stdin); 29 int w; 30 while(~scanf("%d", &n)) { 31 memset(dp, 0, sizeof(dp)); 32 for(int i = 1; i <= n; i++) { 33 scanf("%d", &w); 34 dp[w]++; 35 } 36 ll ans = 0; 37 for(int i = 0; i < maxn; i++) { 38 dp[i+1] += dp[i] / 2; 39 ans += dp[i] % 2; 40 } 41 printf("%I64d\n", ans); 42 } 43 return 0; 44 }
B
C:利用fibonacci通项公式,先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);假设给出一个数10234432,
那么log10(10234432)=log10(1.0234432*10^7)【用科学记数法表示这个数】=log10(1.0234432)+7;
log10(1.0234432)就是log10(10234432)的小数部分.
log10(1.0234432)=0.010063744(取对数所产生的数一定是个小数)
再取一次幂:10^0.010063744=1.023443198
取前4位,只需要将这个结果乘1000就可以了。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef long long LL; 23 int f[21]; 24 int n; 25 26 void init() { 27 f[0] = 0; 28 f[1] = 1; 29 for(int i = 2; i < 21; i++) { 30 f[i] = f[i-1] + f[i-2]; 31 } 32 } 33 34 void solve() { 35 if(n < 21) { 36 printf("%d\n", f[n]); 37 } 38 else { 39 int answer; 40 double ans = -0.5 * log10(5.0) + n * log10((1+sqrt(5))/2); 41 ans -= floor(ans); 42 ans = pow(10, ans); 43 answer = int(ans * 1000); 44 printf("%d\n", answer); 45 } 46 } 47 48 int main() { 49 // freopen("in", "r", stdin); 50 init(); 51 while(~scanf("%d", &n)) { 52 solve(); 53 } 54 return 0; 55 }
C
D:找出a数组里第k小的,再找出b数组里第m大的,假如a数组里k小的数都比b数组里m大的数小,那就满足条件。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 const int maxn = 100010; 23 int na, nb; 24 int k, m; 25 int a[maxn], b[maxn]; 26 27 int main() { 28 // freopen("in", "r", stdin); 29 while(~scanf("%d %d", &na, &nb)) { 30 scanf("%d %d", &k, &m); 31 for(int i = 1; i <= na; i++) scanf("%d", &a[i]); 32 for(int i = 1; i <= nb; i++) scanf("%d", &b[i]); 33 sort(a+1, a+na+1); 34 sort(b+1, b+nb+1); 35 if(a[k] < b[nb-m+1]) puts("YES"); 36 else puts("NO"); 37 } 38 39 return 0; 40 }
D
E:某人有n个朋友,这n个朋友有钱数m和关系s两个属性。问如何选择朋友,使得这些朋友之间s最大差距小于d并且钱数是最多。
可以用滑动窗口,将m从小到大,s从大到小排列,这时在一个队列里维护队首和队尾,假如队首和队尾的s差距≥d时,就把队尾扔掉队首入队否则就仅队首入队。此时更新一下当前最大值。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 typedef long long ll; 23 typedef struct Node { 24 int m; 25 int s; 26 }Node; 27 const int maxn = 100010; 28 int n, d; 29 Node f[maxn]; 30 31 bool cmp(Node a, Node b) { 32 if(a.m == b.m) return a.s > b.s; 33 return a.m < b.m; 34 } 35 36 int main() { 37 // freopen("in", "r", stdin); 38 while(~scanf("%d %d", &n, &d)) { 39 for(int i = 1; i <= n; i++) { 40 scanf("%d %d", &f[i].m, &f[i].s); 41 } 42 sort(f+1, f+n+1, cmp); 43 ll curans = 0; 44 ll ans = 0; 45 int front = 1; 46 int tail = 1; 47 while(1) { 48 if(front > n || tail > n) break; 49 if(f[tail].m - f[front].m >= d) 50 curans -= f[front++].s; 51 else curans += f[tail++].s; 52 ans = max(ans, curans); 53 } 54 printf("%I64d\n", ans); 55 } 56 return 0; 57 }
E
F:先排序,知道第1个肯定和第n个离得最远,而和第2个离得最近。同理第n个和第1个离得最远,和第n-1个离得最近。固定这两个,接下来在中间找i,最远的话和1和n比,最近的话和i-1和i+1比。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 const int maxn = 1555555; 23 int n; 24 int x[maxn]; 25 26 int main() { 27 // freopen("in", "r", stdin); 28 while(~scanf("%d", &n)) { 29 for(int i = 1; i <= n; i++) { 30 scanf("%d", &x[i]); 31 } 32 sort(x+1,x+n+1); 33 printf("%d %d\n", abs(x[1]-x[2]), abs(x[1]-x[n])); 34 for(int i = 2; i < n; i++) { 35 printf("%d %d\n", abs(x[i]-x[i-1]<abs(x[i]-x[i+1]))?abs(x[i]-x[i-1]):abs(x[i]-x[i+1]), 36 (abs(x[i]-x[n])>abs(x[i]-x[1]))?abs(x[i]-x[n]):abs(x[i]-x[1])); 37 } 38 printf("%d %d\n", abs(x[n]-x[n-1]), abs(x[1]-x[n])); 39 } 40 return 0; 41 }
F
G:按照从左到右的顺序,找一个子串。使得这个子串看成是上下左右移动步骤的时候可以走回远点。算算每一个子串里上下左右的个数就行了,假如上的次数等于下的次数,左的次数等于右的次数就说明可以回到原点。
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 22 const int maxn = 555555; 23 int n; 24 char str[maxn]; 25 26 int main() { 27 // freopen("in", "r", stdin); 28 while(~scanf("%d", &n)) { 29 scanf("%s", str); 30 int ans = 0; 31 int u, d, l, r; 32 for(int i = 0; str[i]; i++) { 33 u = d = l = r = 0; 34 for(int j = i; str[j]; j++) { 35 if(str[j] == ‘U‘) u++; 36 if(str[j] == ‘D‘) d++; 37 if(str[j] == ‘L‘) l++; 38 if(str[j] == ‘R‘) r++; 39 if(l == r && u == d) { 40 for(int k = i; k <= j; k++) { 41 printf("%c", str[k]); 42 } 43 printf("\n"); 44 ans++; 45 } 46 } 47 } 48 printf("%d\n", ans); 49 } 50 return 0; 51 }
G