问题 G: 展示玩具
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
int a[5005];
int main() {
int n, k;
cin >> n >> k; //总数,最大差值
for(int i = 1; i <= n; i ++) cin >> a[i];
sort(a + 1, a + 1 + n);
int res = 0;
for(int i = 1; i <= n; i ++) {
int p = upper_bound(a + 1, a + 1 + n, a[i] + k) - (a + 1);
res = max(res, p - i + 1);
}
return cout << res, 0;
}
问题 H: ok 字符串
答案:
int main() {
int n, k;
cin >> n >> k; //字符串总长度,可以被修改的字符数
string s;
cin >> s;
int a[26];
memset(a, 0, sizeof(a));
int res = 0, maxx = 0;
for (int i = 0, j = 0; i < s.size(); i++)
{
int x = s[i] - 'a';
a[x]++;
maxx = max(maxx, a[x]); //出现最多的字符出现了多少次
if (i - j + 1 - maxx > k)
{
a[s[j] - 'a']--;
j++;
}
res = max(res, i - j + 1);
}
cout << res << endl;
return 0;
}
测试代码,用于观察中间结果:
int main() {
int n, k;
cin >> n >> k; //字符串总长度,可以被修改的字符数
string s;
cin >> s;
int a[26];
memset(a, 0, sizeof(a));
int res = 0, maxx = 0;
for (int i = 0, j = 0; i < s.size(); i++)
{
int x = s[i] - 'a';
cout << "\ntext " << "x=" << x << " j=" << j << " ";//
a[x]++;
cout << "A[x]=" << a[x] << " ";//
maxx = max(maxx, a[x]); //出现最多的字符出现了多少次
cout << "maxx=" << maxx << " ";//
if (i - j + 1 - maxx > k)
{
cout << "[YYY]" << "i-j+1=" << i - j + 1 << " ";
a[s[j] - 'a']--;
cout << "j=" << j << " " << "j+1=" << j + 1 << " ";//
j++;
}
res = max(res, i - j + 1);
cout << "res=" << res << endl;//
}
cout << res << endl;
return 0;
}
问题 I: 圣诞树
const int maxn = 5100;
struct node {
ll b, p;
} a[maxn], b[maxn]; //人民币,美金
bool cmp(node a, node b) {
return a.b > b.b;
}
int main()
{
ll n, c, d;
cin >> n >> c >> d; //圣诞树总数,人民币,美金
ll cnta = 0, cntb = 0;
for (int i = 1; i <= n; i++) {
char op[2];
ll bb, p;
cin >> bb >> p >> op;
if (op[0] == 'C') a[++cnta] = {bb, p};
else b[++cntb] = {bb, p};
}
ll res = 0;
for (int i = 1; i <= cnta; i++) { //人民币买,两颗,最漂亮
for (int j = i + 1; j <= cnta; j++) {
if (a[i].p + a[j].p <= c) res = max(res, a[i].b + a[j].b);
}
}
for (int i = 1; i <= cntb; i++) { //美元买,两颗,最漂亮
for (int j = i + 1; j <= cntb; j++) {
if (b[i].p + b[j].p <= d) res = max(res, b[i].b + b[j].b);
}
}
for (int i = 1; i <= cnta; i++) { //人民币买一棵,美元买一棵,最漂亮
for (int j = 1; j <= cntb; j++) {
if (a[i].p <= c && b[j].p <= d) res = max(res, a[i].b + b[j].b);
}
}
cout << res << endl; //结果就是最最漂亮的
return 0;
}
问题 K: 促销骰子
code:
int a[5005];
int main()
{
int cnt = 1; //扔骰子次数
while (1) {
cin >> a[cnt];
if (a[cnt] != 6 || cnt == 3) break; //不是6或掷满三次,停止
cnt ++;
}
//找6
if (cnt == 1) puts("0"); //扔第一次就不是6,仅扔了一次而已
else if (cnt == 2) puts("10");//扔第二次是6
else if (cnt == 3) { //扔了三次,前两次都是6,看第三次...
if (a[3] == 6) puts("1000");
else puts("100");
}
return 0;
}
问题 A: God Sequence
翻译:
如果b>=a,那么先输出长度为b的-1,-2,-3…
然后输出长度为a-1的1,2,3…,最后一个数让序列和为0即可
如果a>=b,那么先输出长度为a的1,2,3…
然后输出长度为b-1的-1,-2,-3…,最后一个数让序列和为0即可.
code:
int main()
{
int a, b;
cin >> a >> b;
if (b >= a) {
int sum = 0;
for (int i = 1; i <= b; i++) {
cout << -i << ' ';
sum += -i;
}
for (int i = 1; i <= a - 1; i++) {
cout << i << ' ';
sum += i;
}
cout << -sum << endl;
} else {
int sum = 0;
for (int i = 1; i <= a; i++) {
cout << i << ' ';
sum += i;
}
for (int i = 1; i <= b - 1; i++) {
cout << -i << ' ';
sum -= i;
}
cout << -sum << endl;
}
return 0;
}
问题 B: ARC Wrecker
翻译:
对于题目给定的一个数组,取出一个数,把比该数大的数都进行减一,求最后数组所有可能出现的额情况
思路:对数组排序
a[n-1]!=a[n],那么a[n]可以不变,也可以最多减到a[n-1],因此方案数为(a[n]-a[n-1]+1).
当a[n]减到a[n-1]时,之后的操作和a[n-1]同步了,可以看作合并了,直接不管
ll a[2000005];
int main()
{
ll n;
cin >> n;
for (ll i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] == a[i - 1]) n --, i --;
}
sort(a + 1, a + 1 + n);
ll lst = 1;
a[0] = 0;
for (ll i = n; i >= 1; i--) {
lst = (lst * (a[i] - a[i - 1] + 1)) % 1000000007;
}
cout << lst << endl;
return 0;
}