题意:
给定一个n
一二三列之和为n
第一列小于第二列 第二列大于第三列
思路:
- n为3的倍数
- n不为3的倍数
- 注意第三列等于0 要做处理
- 具体看代码吧
Code:
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int n;
cin >> n;
if (n % 3 == 0)
{
int a = n / 3;
int b = a + 1;
int c = n - a - b;
if (c == 0)
{
a -= 1;
c += 1;
}
printf("%d %d %d\\n", a, b, c);
}
else
{
int a = n / 3 + 1;
int b = a + 1;
int c = n - a - b;
if (c == 0)
{
a -= 1;
c += 1;
}
printf("%d %d %d\\n", a, b, c);
}
}
int main()
{
int t;
cin >> t;
while (t --)
{
solve();
}
// system("pause");
return 0;
}
题意:
给定两个数组a b
可以对数组a做操作=>全员减一(下界为0)
问是否能让a = b
思路:
- 只要存在ai>bi 就不可能成功让a = b
- 数组c 记录数组a b 差值
- 数组d 复制数组c 并排序 有数组成员为负数直接输出NO
- 利用数组d 的最大值做标准值 遍历 ci 若 ci <dn 则需要bi == 0 否则不能成功
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
int a[N], b[N], c[N], d[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++)
cin >> b[i];
for (int i = 1; i <= n; i ++)
c[i] = a[i] - b[i];
for (int i = 1; i <= n; i ++)
d[i] = c[i];
sort(d + 1, d + 1+n);
for (int i = 1; i <= n; i ++)
{
if (d[i] < 0)
{
puts("NO");
return;
}
}
for (int i = 1; i <= n; i ++)
{
if (c[i] < d[n])
{
if (b[i] == 0)
continue;
else
{
puts("No");
return;
}
}
}
puts("YES");
return;
}
int main()
{
int t;
cin >> t;
while (t --)
{
solve();
}
system("pause");
return 0;
}
题意:
n个连续任务 给出任务时间si 完成任务时间 fi
这些任务是按照其来时的顺序完成的
求每个任务持续时间di
思路:
- 直接的公式为 di=fi-si
- 任务过来时 可能还在执行之前的任务 这种情况di=fi-f{i-1}
- 若是 2 中的情况 fi-f{i-1}<fi-si 所以用min来维护
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int s[N], f[N], d[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> s[i];
for (int i = 1; i <= n; i ++)
cin >> f[i];
for (int i = 1; i <= n; i ++)
{
d[i] = min(f[i]-s[i], f[i] - f[i-1]);
}
for (int i = 1; i <= n; i ++)
printf("%d ", d[i]);
printf("\\n");
}
int main()
{
int t;
cin >> t;
while (t --)
{
solve();
}
system("pause");
return 0;
}
题意:
长度为n 的字符串 有黑色白色不同属性覆盖
为了使条纹上有一段连续的k个黑色单元格,最少需要多少个白色单元格变黑
思路:
- 前缀和
- 只有白色需要改变
- 记白色1 黑色为0
- 遍历长度为k 的前缀和数组差值 并用min维护
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int sum[N];
void solve()
{
int n, k, t = 0;
string s;
cin >> n >> k;
cin >> s;
for (int i = 1; i <= n; i ++)
sum[i] = sum[i - 1] + (s[i - 1] == 'w' ? 1 : 0);
int res = 1e9;
for (int i = k; i <= n; i ++)
res = min(res, sum[i]-sum[i-k]);
cout << res << endl;
}
int main()
{
int t;
cin >> t;
while (t --)
{
solve();
}
system("pause");
return 0;
}
题意:
n个货物 价值为ai
成本为(ai+aj)/ k 四舍五入
问使销售收入达到最大
思路:
- 结果为成本最低
- 最优的情况就是将两个货物之和组合为k 的倍数 完全利用
- 即 将两货物的余数尽可能组合到k
- 可以先对每个货物取余数 得到k 的倍数加进res 并用余数更新价值ai
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;
ll n, k, res;
void solve()
{
res = 0;
cin >> n >> k;
vector<ll> a(n);
for (int i = 0; i < n; i ++)
{
cin >> a[i];
res += a[i] / k;
a[i] %= k;
}
sort(a.begin(), a.end());
int l = 0, r = n - 1;
while (l < r)
{
if (a[l] + a[r] < k)l++;
else
{
res++;
r--;
l++;
}
}
cout << res << endl;
}
int main()
{
int t;
cin >> t;
while (t --)
{
solve();
}
system("pause");
return 0;
}