1.202203 -1 未初始化警告
这道题虽然题目很绕,但是只有两个意思:
1.每个表达式的右值必须在式子出现之前被初始化
2.每个表达式的左值在表达式结束后被初始化
题目的目的也很简单:找到所有不符合题意1的右值数量
思路:哈希表,对于每个式子,先判断右值是否在哈希表里,再给左值赋值
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, k,cnt=0;
cin>>n>>k;
int hash[n+1] = {0};
hash[0] = 1;
for(int i = 0 ; i < k; i++){
int a , b;
cin>>a>>b;
if(hash[b] == 0){
cnt++;
hash[a] = 1;
}
else if(hash[b] == 1){
hash[a] = 1;
}
}
cout<<cnt;
}
2.202203-2 出行计划
题目很简单,但是要理清楚先后顺序,不要被输入顺序牵着逻辑走,这里分享一下我的逻辑顺序,首先是m次查询,也就是起点,去做核酸,然后等待wait的时间,此时拥有了核酸检测报告。然后是时间和要求,必须在某个时间段,具有一份规定时间内做的核酸检测报告,这样有效的里程+1
首先是90分的简单模拟(就是有兴趣的看一下,别复制错了)
#include<vector>
using namespace std;
int main()
{
vector<int>time;
vector<int>limit;
int num, sign, wait;
cin >> num >> sign >> wait;
vector<int>done;
vector<int>ret;
for (int i = 0; i < num; i++)
{
int a, b;
cin >> a >> b;
time.push_back(a);
limit.push_back(b);
}
for (int i = 0; i < sign; i++)
{
int t;
cin >> t;
done.push_back(t);
}
for (auto l : done)
{
int gettime = l + wait;
int count = 0;
for (int i = 0; i < num; i++)
{
if (gettime <= time[i] && gettime + limit[i] > time[i])
{
count++;
}
}
cout<<count<<endl;
}
return 0;
}
为啥模拟能拿90分?虽然说枚举胜标算,暴力破百万,但为啥这么夸张?
首先是vector,比定长数组更快,花费空间更小,还有范围for的使用,也间接提速了
其次是满分的前缀和(我也不太确定这个叫啥,反正不是纯种的前缀和,但绝对算动态规划的范畴)(复制这个)
逻辑也很简单,首先将每次查询搞出来一个获得核酸报告的时间,然后做一个ret数组,利用每次行程的有效期去更新数组,dp[i]表示在i时间有几个行程可以选择,此外,注意一些细节即可
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int>time;
vector<int>limit;
int num, sign, wait;
cin >> num >> sign >> wait;
vector<int>done;
int a, b;
for (int i = 0; i < num; i++)
{
cin >> a >> b;
time.push_back(a);
limit.push_back(b);
}
vector<int>ret(a+1000);
for (int i = 0; i < num; i++)
{
int r=time[i];
int l = time[i] - limit[i] + 1;
for (int j = r; j > 0 && j >= l; j--)
{
ret[j]++;
}
}
for (int i = 0; i < sign; i++)
{
int t;
cin >> t;
t = t + wait;
cout << ret[t] << endl;
}
return 0;
}
3.202203 -3 计算资源调度器
眼前一黑......题目也太长了吧?不过,基于高中做理综大题的经验,题目越长,题目越简单(吗),我看了好几遍才理解了题意
首先要理清题目中的关系,一个应用有多个计算任务,不同的计算任务要在一些计算区域上进行,可能对区域或者区域中的应用有要求,现在要解决这些要求
其次, 要确定存储结构
这就要有一个数组存储着任务与区域的关系,以便验证对应关系
这就要用一个二维vector(后来用了set去重,一个道理)来存储应用以及这个应用所在的区域
和上一个同理
接下来是判断逻辑
这就说明过度有两个阶段:
1.找出符合全部要求的点
2.1失败了,在paari允许的情况下,找出符合1,2的点
告诉我们要有一个存储结构来存储不同计算节点的任务数
接下来是完整代码(复制)
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<set>
#include<cmath>
#include<algorithm>
using namespace std;
int signnum[1020] = { 0 };
unordered_map<int, unordered_set<int>>app;
unordered_map<int, int>tasknum;
bool signqinghe(int sign, int pos)
{
return sign == 0 || signnum[pos] == sign;
}
bool missonqinghe(int apply, int pos)
{
if (apply == 0)
{
return true;
}
int signpos = signnum[pos];
for (auto l : app[apply])
{
if (signpos == signnum[l])
{
return true;
}
}
return false;
}
bool fmissonqinghe(int apply, int posnot)
{
if (apply == 0)
{
return true;
}
for (auto l : app[apply])
{
if (l==posnot)
{
return false;
}
}
return true;
}
int main()
{
int pointnum, fieldnum;
cin >> pointnum >> fieldnum;
for (int i = 1; i <= pointnum; i++)
{
int t;
cin >> t;
signnum[i] = t;
}
int groupnum;
cin >> groupnum;
for (int i = 0; i < groupnum; i++)
{
int fi, ai, nai, pai, paai, paari;
cin >> fi >> ai >> nai >> pai >> paai >> paari;
for (int j = 0; j < fi; j++)
{
set<int>th;
set<int>se;
for (int k = 1; k <= pointnum; k++)
{
if (signqinghe(nai, k) && missonqinghe(pai, k))
{
if (fmissonqinghe(paai, k))
{
th.insert(k);
}
se.insert(k);
}
}
if (th.size() == 0 && paari == 0)
{
th = se;
}
if (th.size() == 0)
{
cout << 0 <<' ';
continue;
}
else
{
vector<pair<int, int>>node;
for (auto i1 : th)
node.push_back({tasknum[i1],i1});
sort(node.begin(), node.end());
int result = node[0].second;
cout << result << " ";
app[ai].insert(result);
tasknum[result]++;
}
}
cout << endl;
}
return 0;
}
signnum存储着不同计算区域的节点编号
app存储着不同应用的计算区域的分布情况
tasknum存储着不同计算区域的任务数量
bool signqinghe(int sign, int pos)
{
return sign == 0 || signnum[pos] == sign;
}
对应要求1
bool missonqinghe(int apply, int pos)
{
if (apply == 0)
{
return true;
}
int signpos = signnum[pos];
for (auto l : app[apply])
{
if (signpos == signnum[l])
{
return true;
}
}
return false;
}
对应要求2
bool fmissonqinghe(int apply, int posnot)
{
if (apply == 0)
{
return true;
}
for (auto l : app[apply])
{
if (l==posnot)
{
return false;
}
}
return true;
}
对应要求3
主函数:输入节点数和区域数,更新signnum,再输入要求数量,设置一个循环(fi表示有几个要求相同的点),设置两个哈希表分别对应符合两个要求和三个要求,遍历计算节点,更新两个哈希表的内容,然后根据题目中给定的排序操作,把符合条件的点进行排序(pair默认先排first再排second,把任务最少的计算节点挑出来作为结果,然后更新app和tasknum数组)