B. Palindromic Numbers
题意
给定一个位数为n的数字,要求构造一个与该数位数相同且与该数和为回文数的数字
思路
n的取值上限为1e5,因此考察高精度减法。
构造出一个与给定数字的差为n位数字的回文数。
方法:
- 若该数最高位为9,则构造n+1位全为1的回文数,其与该数的差必然为n位数字
- 若该数最高位小于9,则构造n位全为9的回文数,其与该数的差必然为n位数字
代码实现
vector<int> sub(vector<int> a,vector<int> b) {
vector<int> c;
int t = 0;
for (int i = 0; i <a.size(); i++)
{
t = a[i]-t;
if (i < b.size()) t -= b[i];
if (t < 0) {
c.push_back(t + 10);
t = 1;
}
else {
c.push_back(t);
t = 0;
}
}
int m = c.size()-1;
while (c[m] == 0 && c.size()) {
c.pop_back();
m = c.size() - 1;
}
return c;
}
void solve() {
int t = 0;
cin >> t;
while (t--)
{
int len = 0;
vector<int> a;
vector<int> b;
string s;
cin >> len>> s;
int siz = s.size();
for (int i = siz - 1; i >= 0; i--) a.push_back(s[i]-'0');
if (s[0] == '9') for (int i = siz; i >= 0; i--) b.push_back(1);
else for (int i = siz - 1; i >= 0; i--) b.push_back(9);
vector<int> c;
c = sub(b,a);
for (int i = c.size() - 1; i >= 0; i--) cout << c[i];
cout << endl;
}
return;
}
C. Helping the Nature
题意
给定长度为n的序列,每次可选择三种操作中的任意一项:
- a[1]——a[i] 均 -1
- a[i]——a[n] 均 -1
- a[1]——a[n]均 +1
则至少要进行多少次操作才能将整个序列全部置0
思路
区间操作:考虑前缀和与差分
原序列全部置零,实际上也是差分序列全部置0
对原序列的三个操作,转化为对差分序列的三个操作:
- b[1]-1,b[i+1]+1
- b[i]-1
- b[1]+1
不难发现,我们只需要对b1-bn中不为0的bi单独处理即可
因此步骤如下:
- bi>0 → 进行第二步操作
- bi<0 → 进行第一步操作
- 最后将b1置0
PS:注意开long long
代码实现
void solve() {
int t = 0;
cin >> t;
while (t--)
{
res = 0;
int n = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = a[i] - a[i - 1];
}
for (int i = n; i > 1; i--)
{
if (b[i] >= 0) {
res += b[i];
}
else {
res -= b[i];
b[1] += b[i];
}
}
res += abs(b[1]);
cout << res << endl;
}
return;
}
D. River Locks
题意
有n个水箱(不知道lock啥意思,就这么叫吧),每个水箱的体积为vi。每个水箱的上方,都有一个水管,我们可以任选一定数量的水管将其打开。每个水管1秒流入下方水箱1体积的水,若该水箱水已满,则溢出部分转移到下一个水箱,下一个水箱亦然。
有q次询问,每一次询问,在ti的时间内至少要打开多少水管才能保证全部水箱都装满水
思路
首先考虑将所有水箱看作整体,思考答案可能为
?
∑
v
i
t
?
\lceil \frac {\sum vi}{t} \rceil
?t∑vi?? 但实际上不可行,因为可能出现后面水箱溢出但前面水箱仍未装满的情况。
举个例子:v1 = 10,v2 = 1,t = 5,则上式结果为3,但3秒时1号水箱显然没装满,所以上式不正确。
我本来想的是单独处理1号水箱,但会出现“前面未满,后面溢出”情况的不止1号水箱和它之后的水箱,第i号水箱和它之后的水箱都可能出现这种情况,因此这种想法显然是不全面的。
所以我们从“最少需要的时间”入手,考虑注满前i个水箱(i=1,2,3,······,n)所至少需要的时间的最大值minn,来保证每个水箱都可以在该时间时注满
ti<minn ,必定无法在ti内注满所有水箱ti>minn ,必定可以在ti内注满所有水箱,且需要的最少水管数量为(minn + ti -1)/ti
PS:学到了除数为x时对商上取整的方法 →(num+x-1)/x
代码实现
void solve() {
int n = 0;
cin >> n;
ll minn = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
minn = max(minn, (s[i] + i - 1) / i);
}
int t = 0;
cin >> t;
while (t--) {
int tim = 0;
cin >> tim;
if (tim < minn) cout << "-1"<<endl;
else cout << (s[n] + tim - 1) / tim << endl;
}
return;
}
|