耻辱场。做出三道题,但每道题平均交了4遍还多,第一题没有第一眼想出正确答案,Rating还是-60,心累。感觉还是要放平心态,求稳。并且多做思维题,思维还是过于僵化。
实时Rating:1304,不能再低了,再低真对不起我自己了。
给定一个 n n n,要求一个 n n n位数 s s s,满足: s s s的每一位都不为0,且s不能被组成它的每个数字整除。 n ≤ 1 0 5 n \le 10^5 n≤105。
说实话我没有先敲出来这个题。既然 n n n这么大一定不能套数了。赛场上用计算器摆了好几种关于和「7」有关的数,我也不知道为什么当时对7有如此的执念,明明小数点后面会循环,数长了之后总会能除开的……最后发现
77777 … 4 ‾ \overline{77777\dots4} 77777…4
的小数点后永远是.5,于是提交通过。提交时由于太过急躁,第一次选错了语言,后几次试了错误的答案。这题答案不唯一,标解是用了
23333 … 3 ‾ \overline{23333\dots3} 23333…3
#include
typedef long long ll;
ll nextInt()
{
ll num = 0;
char c = 0;
bool flag = false;
while ((c = std::getchar()) == ' ' || c == '\r' || c == '\t' || c == '\n');
if (c == '-')
flag = true;
else
num = c - 48;
while (std::isdigit(c = std::getchar()))
num = num * 10 + c - 48;
return (flag ? -1 : 1) * num;
}
const size_t _Siz = 103020;
int T;
int main(int argc, char **argv)
{
T = nextInt();
while (T--)
{
int n = nextInt();
if (n == 1)
{
std::cout << -1 << std::endl;
continue;
}
for (int i = 1; i <= n - 1; i++)
std::cout << 7;
std::cout << 4 << std::endl;
}
return 0;
}
给定一个数组 a a a,由非负整数构成,给定数组 x x x,规定 x i = m a x ( a 1 , a 2 , … , a i − 1 ) x_i = max(a_1, a_2, \dots, a_{i - 1}) xi=max(a1,a2,…,ai−1),给定数组 b i = a i − x i b_i = a_i - x_i bi=ai−xi。现已知数组 b b b,要求倒推出 a a a。
纯模拟。没啥技术含量。根据题目, a i = b i + x i a_i = b_i + x_i ai=bi+xi,显然 x i x_i xi可求,就是 b 1 b_1 b1到 b i − 1 b_i - 1 bi−1取个max。然后加起来就完事。
这题交了好几遍,就是因为没有读好题,把题目想得过于简单。
#include
#define debug(X) std::cout << #X << " : " << X << std::endl
typedef long long ll;
ll nextInt()
{
ll num = 0;
char c = 0;
bool flag = false;
while ((c = std::getchar()) == ' ' || c == '\r' || c == '\t' || c == '\n');
if (c == '-')
flag = true;
else
num = c - 48;
while (std::isdigit(c = std::getchar()))
num = num * 10 + c - 48;
return (flag ? -1 : 1) * num;
}
const size_t _Siz = 503020;
ll T, b[_Siz] = { 0 }, t[_Siz] = { 0 };
int main(int argc, char **argv)
{
int n = nextInt();
ll Mx = 0;
bool flag = false;
for (int i = 1; i <= n; i++)
{
b[i] = nextInt();
t[i] = (t[i - 1] + b[i] > t[i - 1]) ? (t[i - 1] + b[i]) : t[i - 1];
}
std::cout << b[1] << ' ';
for (int i = 2; i <= n; i++)
std::cout << t[i - 1] + b[i] << ' ';
std::cout << std::endl;
}
给定一个排列 p p p,再给定一个 k k k,使得 p p p可以被分成不相交的 k k k份,定义 v a l u e value value为各份最大值的和,求 v a l u e value value的值和所有满足的 v a l u e value value的方案数。
这题交了7遍,还是没过。第一问求 v a l u e value value好办,直接前 k k k大加起来即可。第二问的话,要选定一个分界线,分界线可以放在前k大的数字后面到下一个数字前。设两个数字位置为 p o s i pos_i posi和 p o s i + 1 pos_{i + 1} posi+1,则方案数有 p o s i + 1 − p o s i pos_{i + 1} - pos_i posi+1−posi个,然后乘起来就好。
#include
#define debug(X) std::cout << #X << " : " << X << std::endl
typedef long long ll;
const ll mod = 998244353ll;
ll nextInt()
{
ll num = 0;
char c = 0;
bool flag = false;
while ((c = std::getchar()) == ' ' || c == '\r' || c == '\t' || c == '\n');
if (c == '-')
flag = true;
else
num = c - 48;
while (std::isdigit(c = std::getchar()))
num = num * 10 + c - 48;
return (flag ? -1 : 1) * num;
}
int main(int argc, char **argv)
{
int n, k, p = -1, ans = 1, sum = 0;
n = nextInt(), k = nextInt();
for (int i = 1; i <= n; i++)
{
int x = nextInt();
if (x >= (n - k + 1))
{
sum += x;
if (p != -1)
ans = ans * (i - p) % mod;
p = i;
}
}
std::cout << sum << ' ' << ans << std::endl;
return 0;
}
给定一个字符串,要求它里面的回文子串,满足:该字串由两段组成,前段是原串的前缀,后段是原串的后缀。
纯模拟,蛮练手的这个题。确定下思路之后往下写就好了。Hard version没测,目测应该也能过。
#include
#define debug(X) std::cout << #X << " : " << X << std::endl
typedef long long ll;
ll nextInt()
{
ll num = 0;
char c = 0;
bool flag = false;
while ((c = std::getchar()) == ' ' || c == '\r' || c == '\t' || c == '\n');
if (c == '-')
flag = true;
else
num = c - 48;
while (std::isdigit(c = std::getchar()))
num = num * 10 + c - 48;
return (flag ? -1 : 1) * num;
}
const size_t _Siz = 503020;
ll T;
std::string st;
bool palin(std::string stx, int l, int r)
{
std::string st2 = stx.substr(l, r - l + 1);
std::string st1 = st2;
std::reverse(st1.begin(), st1.end());
return (st1 == st2);
}
int main(int argc, char **argv)
{
T = nextInt();
while (T--)
{
std::cin >> st;
int len = st.length();
if (len == 1)
{
std::cout << st << std::endl;
continue;
}
if (len == 2)
{
if (st[0] == st[1])
std::cout << st << std::endl;
else
std::cout << st[0] << std::endl;
continue;
}
std::string ans, anst;
int head = 0, tail = len - 1;
while (head != tail && head != tail - 1)
{
if (st[head] == st[tail])
ans += st[head];
head++;
tail--;
}
if (head == 1 && tail == len - 2)
{
head = 0, tail = 1;
int t1 = 0, t2 = 0;
while (palin(st, 0, tail++)) t1++;
head = len - 2, tail = len - 1;
while (palin(st, head--, len - 1)) t2++;
if (t1 >= t2)
std::cout << st.substr(0, t1) << std::endl;
else
std::cout << st.substr(len - t2, len - 1) << std::endl;
continue;
}
int p = head, q = tail, r = 0, s = 0;
for (q = tail; q > p; q--)
if (palin(st, p, q))
{
r = q;
anst += st.substr(p, q - p + 1);
break;
}
for (p = r + 1; p < tail; p++)
if (palin(st, p, tail))
{
anst += st.substr(p, tail - p + 1);
break;
}
std::string tans = ans;
std::reverse(tans.begin(), tans.end());
std::cout << ans + anst + tans << std::endl;
}
}