前面这些题都是一些模拟贪心= =描述还都很长。。。
100513I - Sale in GameStore
可以买任意一个游戏,然后可以选任意个加起来价值小于这个游戏的求最多能有几个。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define FIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define FILEREAD freopen("input.txt", "r", stdin);
const int INF = 0x3f3f3f3f;
const int N = 2001;
const int MOD = 1e9 + 7;
int main()
{
#ifndef ONLINE_JUDGE
FILEREAD
#endif
FIO
int n;
cin >> n;
int p[N];
for (int i = 0; i < n; ++i)
cin >> p[i];
if (n == 1) {
cout << 1 << endl;
return 0;
}
sort(p, p + n);
int ans = 0, sum = 0;
for (int i = 0; i < n - 1; ++i) {
sum += p[i];
if (sum <= p[n - 1])
ans = i;
else
break;
}
cout << ans + 2 << endl;
return 0;
}
100513F - Ilya Muromets
可以从序列中拿去长度为k的连续区间,然后再从新的序列中拿去长度为k的连续区间,求能拿走的最大和。DP[i][0/1/2]表示第i个前拿了j段的最大值。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;
int n, k;
int a[maxn];
int sum[maxn], dp[maxn][3];
int main()
{
//freopen("H:\\in.txt","r",stdin);
//freopen("H:\\out.txt","w",stdout);
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i];
if (2 * k >= n)
{
printf("%d\n", sum[n]);
return 0;
}
int max1 = 0, max2 = 0;
dp[0][0] = dp[0][1] = dp[0][2] = 0;
for (int i = k; i <= n; i++)
{
dp[i][1] = max(dp[i-1][1], dp[i-k][0] + sum[i] - sum[i-k]);
dp[i][2] = max(dp[i-1][2], dp[i-k][1] + sum[i] - sum[i-k]);
}
int ans = dp[n][2];
//printf("%d\n", ans);
for (int i = 2 * k; i <= n; i++)
ans = max(ans, sum[i] - sum[i-2*k]);
printf("%d\n", ans);
return 0;
100513M - Variable Shadowing
一个变量如果已经定义过,在更深层的括号里面定义编译器会发出警告,给出代码输出警告信息。刚开始用stack做有点麻烦改用手动维护层数。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;
char s[55][55];
int len[55];
vector<pii> pos[30];
map<pii, int> mp;
void clear(int lv)
{
for (int i = 0; i < 26; i++)
while (pos[i].size() && mp[MP(pos[i][pos[i].size()-1].first, pos[i][pos[i].size()-1].second)] > lv)
pos[i].erase(pos[i].end()-1);
}
int main()
{
//freopen("H:\\in.txt","r",stdin);
//freopen("H:\\out.txt","w",stdout);
int n;
scanf("%d", &n);
getchar();
for (int i = 1; i <= n; i++)
gets(s[i] + 1), len[i] = strlen(s[i] + 1);
int lv = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= len[i]; j++)
if (s[i][j] == '{')
lv++;
else if (s[i][j] == '}')
{
lv--;
clear(lv);
}
else if (s[i][j] == ' ') ;
else
{
//printf("%d %d %d\n", i, j, lv);
int num = s[i][j] - 'a';
if (pos[num].size())
{
printf("%d:%d: warning: shadowed declaration of %c, the shadowed position is %d:%d\n", i, j, s[i][j], pos[num][pos[num].size()-1].first, pos[num][pos[num].size()-1].second);
}
pos[num].push_back(MP(i, j));
mp[MP(i, j)] = lv;
}
return 0;
}
100513D - Data Center
能量超过所需的情况下尽量让低电压的服务器更少。
贪心模拟,被坑的一题
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
#define FIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
#define FILEREAD freopen("input.txt", "r", stdin);
const int INF = 0x3f3f3f3f;
const int N = 200001;
const int MOD = 1e9 + 7;
struct server {
long long a;
int l, id;
} s[N];
vector<int> low, high;
int main()
{
#ifndef ONLINE_JUDGE
FILEREAD
#endif
FIO
int n;
long long m;
cin >> n >> m;
for (int i = 0; i < n; ++i) {
cin >> s[i].a >> s[i].l;
s[i].id = i + 1;
}
sort(s, s + n, [](server &x, server &y){return x.a > y.a;});
int r = 0;
long long sum = 0;
for (int i = 0; i < n; ++i) {
sum += s[i].a;
if (sum >= m) {
r = i + 1;
break;
}
}
long long sl = 0, sh = 0;
for (int i = 0; i < n; ++i)
if (s[i].l) {
low.push_back(i);
sl += s[i].a;
}
else
high.push_back(i);
int llast = low.size(), hlast = r - llast;
while (hlast < 0) {
sl -= s[low[--llast]].a;
++hlast;
}
for (int i = 0; i < hlast; ++i)
sh += s[high[i]].a;
while (sl + sh < m) {
sl -= s[low[--llast]].a;
sh += s[high[hlast++]].a;
}
cout << r << ' ' << llast << endl;
for (int i = 0; i < llast; ++i)
cout << s[low[i]].id << ' ';
for (int i = 0; i < hlast; ++i)
cout << s[high[i]].id << ' ';
return 0;
}
100513G - FacePalm Accounting
修改尽量少让序列的每个长度为K的区间的和都小于0,修改之后不能小于原数组的最小值。首先肯定尽量加在右边最好,然后暴力就行了。虽然最坏的时候他要跑k-1次才能减,但是均摊下来就可以了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;
LL a[maxn];
int main()
{
//freopen("H:\\in.txt","r",stdin);
//freopen("H:\\out.txt","w",stdout);
int n, k;
LL mmin = INF;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]), mmin = min(mmin, a[i]);
LL sum = 0, ans = 0;
for (int i = 1; i < k; i++)
sum += a[i];
for (int i = k; i <= n; i++)
{
sum += a[i];
sum -= a[i-k];
if (sum >= 0)
{
ans += sum + 1;
LL t = sum + 1;
int now = i;
while (t)
{
LL sub = min(t, a[now]-mmin);
a[now] -= sub;
t -= sub;
now--;
}
sum = -1;
}
}
printf("%lld\n", ans);
for (int i = 1; i <= n; i++)
printf("%lld ", a[i]);
puts("");
return 0;
}
100513E - Election of a Mayor
所有选区有对面的得票和自己的得票,需要自己赢的选区超过总选区的一半才能胜利,可以合并相邻的两个选区,但是合并之后的选区不能再合并,求要合并多少个选区才能赢。
贪心的合并就行了,只要能增加一个获胜的选区或者减少一个失败的选区就可以合并,这样合并出来一定是最佳的,然后选出一些输出就行了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;
int n;
int m[maxn], r[maxn];
int main()
{
//freopen("H:\\in.txt","r",stdin);
//freopen("H:\\out.txt","w",stdout);
scanf("%d", &n);
int win = 0;
for (int i = 0; i < n; i++)
{
scanf("%d%d", &m[i], &r[i]);
if (m[i] > r[i]) win++;
}
vector<pii> ans;
for (int i = 1; i < n; i++)
{
int w = 0;
if (m[i] > r[i]) w++;
if (m[i-1] > r[i-1]) w++;
if (w == 1)
{
if (m[i] + m[i-1] > r[i] + r[i-1])
{
ans.push_back(MP(i-1, i));
i++;
}
}
if (w == 0)
{
ans.push_back(MP(i-1, i));
i++;
}
}
if (n - (2 * win - 1) > (int)ans.size())
{
puts("-1");
return 0;
}
else
{
printf("%d\n", max(0, n - (2 * win - 1)));
for (int i = 0; i < n - (2 * win - 1); i++)
printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
}
return 0;
}