签到题其实是CEF,中等题是ABDH,G 很简单只不过某种意义上很难。
公告也写了,不会就跳,不要在一题上死磕。
A Roman and Browser CodeForces - 1100A
题意
给你一个长度为 n 的由 -1 和 1 组成的数组和间隔距离k,选一个位置 b 每隔 k 个删除一个,问你在不同的初始位置 b 的选择中,最后这个数组的总和的绝对值最大。
题解
模拟,数据范围很小,两个 for 循环,遍历所有结果就好。
AC代码
int s[105];
int main() {
int n, k,ans=0;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++)
scanf("%d", s+i);
for (int i = 0; i < k; i++) {
int x = 0;
for (int j = 0; j < n; j++)
if ((j - i) % k != 0)
x += s[j];
x = abs(x);
ans = x > ans ? x : ans;
}
printf("%d", abs(ans));
return 0;
}
B Array Negations Gym - 102152I
题意
题意很简单,给你一个长度为 n 的数组,和变化次数 k 。你要对数组进行 k 次操作,每一次操作是选择一个数字将它取反。
要注意的是,同一个数可以取反多次,比如 1 我取反2次,它还是1。
题解
- 方法一
- 贪心、小根堆
- 思路上很简单就只要把最小的那个数字一直取反就好了,如果那个数字是负数,则会增加总和,如果是零则不影响,如果是正数,那说明目前没有负数和零了,那把它取反对目前的影响也是最小的。
比如:-1,0,1,2 ,k为7。
首先取反-1,变为0,1,1,2,然后0一直是最小,一直取反0不变。
比如:-1,1,2,k为7。
第一次: 1,1,2
第二次: -1,1,2
以此反复 - 实现方法使用的是小根堆(优先队列),它可以在复杂度为O(logn)进行一次插入或删除操作来维护一个有序组,c++ std有直接的实现,可以拿来用,具体看下面代码。
- 方法二
- 贪心
- 这个方法就是纯贪心,只不过比较麻烦,细节比较多,具体就不多讲了,自己体会下。
设数组的负数个数为a,数组为s。
首先对所给的数组排序,之后按一下条件处理。- if (k<=a or s中存在0 or (k-a)%2==0 )
- 从小到大将 min(k,a) 个负数都改为正数,
- elif ((k-a)%2==1)
- 比较最小的正数和最大的负数的绝对值,哪个小就把那个变为负数。
elif (k>n) - 最后判断一次k-n的奇偶性,偶数不变,奇数,将最大的负数变回去。
- 比较最小的正数和最大的负数的绝对值,哪个小就把那个变为负数。
- if (k<=a or s中存在0 or (k-a)%2==0 )
- 方法三
- 贪心
- 此方法由王璐聃同志提供
- 排序后从小到大将负的改正,改完所有负数后,如果剩下次数为奇数并且没有零,那将改完的其中最小的再改一次
AC代码
-
//方法一 priority_queue<int, vector<int>, greater<int> > q; int main() { int t; scanf("%d", &t); while (t--) { int n, k, sum = 0; scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) { int x; scanf("%d", &x); q.push(x); } for (int i = 0; i < k; i++) { int x = q.top(); q.pop(); q.push(-x); } for (int i = 0; i < n; i++) { sum += q.top(); q.pop(); } printf("%d\n", sum); } return 0; }
-
//方法二 int s[10004]; int main() { int t, n, k; scanf("%d", &t); while (t--) { scanf("%d%d", &n,&k); for (int i = 0; i < n; i++) { scanf("%d", s + i); } sort(s, s + n); for (int i = 0; i < k; i++) { if (i >= n) { if ((k - i) % 2) { s[i - 1] = -s[i - 1]; } } if (s[i] < 0) { s[i] = -s[i]; } else { if(s[i]&&(k - i) % 2){ if (i&&s[i - 1] < s[i]) { s[i - 1] = -s[i - 1]; } else { s[i] = -s[i]; } } break; } } int sum = 0; for (int i = 0; i < n; i++) { sum += s[i]; } printf("%d\n", sum); } return 0; }
-
//方法三 #include<bitsdc++.h> using namespace std; int t, a[10010]; int main() { scanf("%d", &t); while (t--) { int n, k; scanf("%d%d", &n, &k); int sum = 0; int flag = 0; for (int i = 0; i < n; i++) { scanf("%d", &a[i]); sum += a[i]; } sort(a, a + n); int ff = 0; for (; a[ff] < 0 && k > 0 && ff < n; k--) { sum = sum - 2 * a[ff]; a[ff] = -a[ff]; ff++; } sort(a, a + n); sum = sum - 2 * (k % 2 * a[0]); printf("%d\n", sum); } return 0; }
C Yet Another Two Integers Problem CodeForces - 1409A
题意
给你两个数a、b,你一次操作可以给a加上-10~10的值,问你最少加几次能把a变成b
题解
贪心
用除法和取模来优化一次一次加减。
答案为 a 与 b 的差值除10,有余数则加1
AC代码
int main() {
int t, a, b;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &a, &b);
int c = abs(a - b);
int ans = c / 10;
if (c % 10 != 0)ans++;
printf("%d\n", ans);
//printf("%d\n", abs(a - b) / 10 + (abs(a - b) % 10 != 0));
}
return 0;
}
D Ping-pong CodeForces - 1455C
题意
两人打球,发球和接球都消耗一体力,给你体力a,b。a先手,问在两个人都最优策略下,优先最大化自己的胜利次数,最小化对手的胜利次数,两人的胜利次数。
题解
博弈
关键点是优先最大化自己的胜利次数。
后手若一直让球直到对方最后一个球发出来时再开始接球,则能满足自己胜场最多,对方胜场最少,而先手因为要先发球,所以本质上完全被后手所主导,自己毫无决策空间。
AC代码
int main() {
int t, a, b;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &a, &b);
printf("%d %d\n", a - 1, b);
}
return 0;
}
E Dislike of Threes CodeForces - 1560A
题意
给你一个数字k,问你第k个不被3整除并且十进制末尾表示没有3的数是什么。
题解
简单题,打个表筛选下,不被3整除并且十进制末尾表示没有3的数就好,数据范围很小,t*k,才1e5,甚至不用打表,直接遍历整数就好
AC代码
int s[3333];
int main() {
int t, k;
scanf("%d", &t);
int cnt = 1;
for (int i = 1; i < 3333; i++) {
if (i % 3 != 0 && i % 10 != 3) {
s[cnt++] = i;
}
}
while (t--) {
scanf("%d", &k);
printf("%d\n", s[k]);
}
return 0;
}
F Book Reading CodeForces - 884A
题意
给你天数和阅读需要时间和每一天的工作时间,问你多久可以读完书
题解
模拟
AC代码
int main()
{
int day = 0,t_day=0;
int n_time = 0 ;
int r_time=0,s_time=0;
int i = 0, j = 0;
scanf("%d%d", &day, &n_time);
for (i = 0; i < day; i++){
scanf("%d", &r_time);
s_time += (86400 - r_time);
if (s_time >= n_time){
t_day = i + 1;
break;
}
}
printf("%d", t_day);
return 0;
}
G 元素周期表 Gym - 102426D
题意
给你简单化学式,求分子质量。
题解
大大大大模拟。由王璐聃同志强烈推荐,不得已加入。
AC代码
double l[] ={
1.008,
4.003,
6.941,
9.012,
10.81,
12.01,
14.01,
16,
19,
20.18,
22.99,
24.31,
26.98,
28.09,
30.97,
32.07,
35.45,
39.95,
39.10,
40.08,
44.96,
47.88,
50.94,
52,
54.94,
55.85,
58.93,
58.69,
63.55,
65.39,
69.72,
72.59,
74.92,
78.96,
79.90,
83.80,
85.47,
87.62,
88.91,
91.22,
92.91,
95.94,
97.91,
101.1,
102.9,
106.4,
107.9,
112.4,
114.8,
118.7,
121.8,
127.6,
126.9,
131.3,
132.9,
137.3,
138.9,
140.1,
140.9,
144.2,
144.9,
150.4,
152,
157.3,
158.9,
162.5,
164.9,
167.3,
168.9,
173,
175,
178.5,
180.9,
183.9,
186.2,
190.2,
192.2,
195.1,
197,
200.6,
204.4,
207.2,
209,
209,
210,
222,
223,
226,
227,
232,
231,
238,
237.1,
244.1,
243.1,
247.1,
247.1,
252.1,
252.1,
257.1,
258.1,
259.1,
262.1,
265.1,
268.1,
271.1,
270.1,
277.2,
276.2,
281.2,
280.2,
285.2,
284.2,
289.2,
288.2,
293.2,
294.2,
294.2
};
string s[] = {
"H",
"He",
"Li",
"Be",
"B",
"C",
"N",
"O",
"F",
"Ne",
"Na",
"Mg",
"Al",
"Si",
"P" ,
"S",
"Cl",
"Ar",
"K",
"Ca",
"Sc",
"Ti",
"V",
"Cr",
"Mn",
"Fe",
"Co",
"Ni",
"Cu",
"Zn",
"Ga",
"Ge",
"As",
"Se",
"Br",
"Kr",
"Rb",
"Sr",
"Y",
"Zr",
"Nb",
"Mo",
"Tc",
"Ru",
"Rh",
"Pd",
"Ag",
"Cd",
"In",
"Sn",
"Sb",
"Te",
"I",
"Xe",
"Cs",
"Ba",
"La",
"Ce",
"Pr",
"Nd",
"Pm",
"Sm",
"Eu",
"Gd",
"Tb",
"Dy",
"Ho",
"Er",
"Tm",
"Yb",
"Lu",
"Hf",
"Ta",
"W",
"Re",
"Os",
"Ir",
"Pt",
"Au",
"Hg",
"Tl",
"Pb",
"Bi",
"Po",
"At",
"Rn",
"Fr",
"Ra",
"Ac",
"Th",
"Pa",
"U",
"Np",
"Pu",
"Am",
"Cm",
"Bk",
"Cf",
"Es",
"Fm",
"Md",
"No",
"Lr",
"Rf",
"Db",
"Sg",
"Bh",
"Hs",
"Mt",
"Ds",
"Rg",
"Cn",
"Nh",
"Fl",
"Mc",
"Lv",
"Ts",
"Og"
};
map<string, double> m;
int main() {
for (int i = 0; i < 118; i++)
m[s[i]] = l[i];
int n;
double sum;
string c;
string x;
string nb;
scanf("%d", &n);
while (n--) {
sum = 0;
cin >> c;
int len = c.size();
for (int i = 0; i < len; i++) {
if (isupper(c[i])) {
x = c[i];
if (islower(c[i + 1]))
x += c[++i];
while (isdigit(c[i + 1]) ){
nb += c[i + 1];
i++;
}
if (nb.empty())nb += "1";
sum += stoi(nb)*m[x];
x.clear();
nb.clear();
}
}
printf("%.3f\n", sum);
}
return 0;
}
H Letters CodeForces - 978C
题意
给出n栋宿舍楼编号为1-n,每栋宿舍楼有ai个宿舍,宿舍编号是从1~a1+a2+...+an,现给出m次查询,每次询问一个编号,问这个编号是第几个宿舍楼的第几个宿舍。m个询问按递增顺序给出。
题解
求出前缀和后二分查找
AC代码
long long h[200010];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld", &h[i]);
h[i] += h[i - 1];
}
for (int i = 1; i <= m; i++) {
long long x;
int j;
scanf("%lld", &x);
j = lower_bound(h,h+n,x)-h;
printf("%d %lld\n", j, x - h[j-1]);
}
return 0;
}