A. Countdown
这是一道简单的思维题,话也就不多说了,直接做
#include <iostream>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
string s;
cin >> n >> s;
int ans = 0;
for(int i = 0; i < s.size() - 1; i++)
{
int t = s[i] - '0';
if(t > 0) ans += t + 1;
}
ans += s[n - 1] - '0';
cout << ans << endl << endl;
}
return 0;
}
B. Swaps
算法:双指针 + 思维
题意:给定a和b两数组,叫你用最小的操作把a数组变的比b小,a数组是1 ~ 2n的奇数,b是1 ~ 2n的偶数。
要解决这道题,a的第一个数一定要b的小,那么这么才可以做到呢? 自己暴力枚举所有的可能的情况,这样的时间复杂度为O(n^2),肯定会超时。
这时,我们可以把a数组的下标也存下来,给a素组按数值排序,然后用双指针来枚举答案,我们只需找到大于a[i]都第一个数,然后2个数都和第一个交换,即为i + j - 2,
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
PII a[N];
int b[N];
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i].first, a[i].second = i;
for(int i = 1; i <= n; i++) cin >> b[i];
sort(a + 1, a + n + 1);
int ans = 2e9;
for(int i = 1, j = 1; i <= n; i++)
{
while(b[j] <= a[i].first) j++;
ans = min(ans, a[i].second + j - 2);
}
cout << ans << endl;
}
return 0;
}
C. Book
算法:dp + 拓扑序列
这道题其实挺容易看出是拓扑序列的,奈何我图论没怎么做,
拓扑序列的话,就是把每个点的入度有那些存下来,当这个点入度为0就可以入队,更新其他点
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int N = 2e5 + 10;
int n;
vector<int> g[N]; // 邻接表存图
int d[N]; // 存每个点的入度
int f[N]; // 存每个章节理解需要的天数
void init()
{
for(int i = 1; i <= n; i++)
g[i].clear(), f[i] = d[i] = 0;
}
int main()
{
int T;
cin >> T;
while(T--)
{
init();
cin >> n;
for(int i = 1; i <= n; i++)
{
int k;
cin >> k;
d[i] = k;
for(int j = 0; j < k; j++)
{
int x;
cin >> x;
g[x].push_back(i);
}
}
queue<int> q;
for(int i = 1; i <= n; i++)
if(!d[i])
{
q.push(i);
f[i] = 1;
}
while(q.size())
{
int u = q.front();
q.pop();
for(auto i : g[u])
{
d[i]--;
/* 其实一开始我也挺疑惑,为什么这里要取max,其实很简单,因为需要把
所有入度的点删去(前置章节理解),才可以理解该章节,所以必须取max
*/
if(u > i) f[i] = max(f[i], f[u] + 1); //当当前的理解的章节的节点大于需要理解的章节
else f[i] = max(f[i], f[u]);
if(!d[i]) q.push(i);
}
}
bool flag = false;
int ans = 0;
for(int i = 1; i <= n; i++)
{
// cout << d[i] << ' ';
ans = max(ans, f[i]);
if(d[i]) flag = true;
}
// cout << endl;
if(flag) puts("-1");
else cout << ans << endl;
}
return 0;
}
这里吐槽一下,这次cf就非常离谱,YYD queue,第二题的评判都等了快一个小时,然后WA了,然后…