Codeforces Round #787 (Div. 3)ABCD
记录一下,感觉写的最好的一次了,前四个思路都很流畅。不过不太会写DFS,D调了很久很久很久 ..,E没什么思路。之后看看题解再做一做。(菜,三月份才开始做,刚到绿名。。)
A. Food for Animals
签到题
#include <iostream>
using namespace std;
void solve()
{
int a, b, c, x, y;
cin >> a >> b >> c >> x >> y;
if(max(x - a, 0) + max(y - b, 0) <= c) puts("YES");
else puts("NO");
return;
}
int main()
{
int t = 1;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
B. Make It Increasing
题意:对任意一个数都能操作任意次数除2,问最少操作多少次,使数组严格递增
思路:可以从倒数第二个开始往前看,若a[i] >= a[i + 1]
就一直除2,直到小于为止;如果发现a[i + 1]
已经是0了,说明当前这个数已经无法再变小了,就输出-1。
#include <iostream>
using namespace std;
const int N = 33;
int a[N];
void solve()
{
int n;
cin >> n;
for(int i = 0; i < n; i ++ )
cin >> a[i];
int ans = 0;
bool flag = true;
for(int i = n - 2; i >= 0; i --)
{
if(a[i + 1] == 0)
{
flag = false;
break;
}
while(a[i] >= a[i + 1])
{
a[i] /= 2;
ans ++;
}
}
if(flag) printf("%d\n", ans);
else puts("-1");
return;
}
int main()
{
int t = 1;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
C. Detective Task
题意:有n个人进来看画,其中有个人会偷走画,在调查时,每个人会回答0(没看到画)、1(看到了画)、?(忘记了),除了小偷之外,说的都是真话,问:有多少个偷画的嫌疑人?
思路:找到一个0,下标为t0;找到第一个1,下标为t1。t0一定有嫌疑,如果t0是偷画人,之后的人都不是嫌疑人;如果t0不是偷画人,t0之前的人要被怀疑,t0之后的不用被怀疑;t1一定有嫌疑,作为最后一个看到画的人,t1之前的都不用被怀疑。因此t1到t0之间的都是嫌疑人。
t0和t1初始化为-1
还要判断特殊情况,如果字符串中没有1和0,即都是?,那么都是嫌疑人;如果有1无0,那么t1到最后都是嫌疑人;如果有0无1,那么开始到t0都是嫌疑人。
#include <iostream>
using namespace std;
void solve()
{
string s;
cin >> s;
int n = s.size();
int t1 = -1, t0 = -1;
for(int i = 0; i < n; i ++ )
if(s[i] == '1') t1 = i;
for(int i = 0; i < n; i ++ )
if(s[i] == '0')
{
t0 = i;
break;
}
int ans = 0;
if(t1 == -1 && t0 == -1) ans = n;
else if(t1 == -1 && t0 != -1) ans = t0 + 1;
else if(t1 != -1 && t0 == -1) ans = n - t1;
else if(t1 != -1 && t0 != -1) ans = t0 - t1 + 1;
printf("%d\n", ans);
return;
}
int main()
{
int t = 1;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
D - Vertical Paths
题意:给定一棵树,求最少的路径数,从上往下能够不重复的包括所有的点
思路:根据给出的每个点的父节点,建图,从父节点到子节点连一条边。从根节点开始dfs遍历,遍历过程中记录路径数。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 200010;
int h[N], e[N], ne[N], idx;
int p[N];
bool st[N];
vector<int> path[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u, int father, int &cnt)
{
for(int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if(!st[u])
{
path[cnt].push_back(j);
st[u] = true;
}
else path[++ cnt].push_back(j);
dfs(j, u, cnt);
}
}
void solve()
{
memset(st, 0, sizeof st);
memset(h, -1, sizeof h);
int n, root;
cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> p[i];
for(int i = 1; i <= n; i ++ )
if(p[i] != i)
add(p[i], i);
else root = i;
int cnt = 1;
path[cnt].push_back(root);
dfs(root, -1, cnt);
printf("%d\n", cnt);
for(int i = 1; i <= cnt; i ++ )
{
printf("%d\n", path[i].size());
for(auto v : path[i])
printf("%d ", v);
path[i].clear();
puts("");
}
puts("");
return;
}
int main()
{
int t = 1;
cin >> t;
while(t --)
{
solve();
}
return 0;
}