L2-041 插松枝
模拟
#include <iostream>
#include <cstring>
#include <stack>
#include <queue>
using namespace std;
int n, m, k;
queue<int> q;
stack<int> s;
void solve()
{
while (1)
{
vector<int> v;
bool flag = 0;
while(1)
{
if (v.empty())
{
if (!s.empty())
{
v.push_back(s.top());
s.pop();
}
else if (!q.empty())
{
v.push_back(q.front());
q.pop();
}
else
{
break;
}
}
else
{
if (!s.empty() && s.top() <= v.back())
{
v.push_back(s.top());
s.pop();
}
else
{
while (!q.empty() && s.size() <= m)
{
auto t = q.front();
if (t <= v.back())
{
q.pop();
v.push_back(t);
break;
}
else
{
if (s.size() == m)
{
flag = 1;
break;
}
else
{
s.push(t);
q.pop();
}
}
}
if (q.empty() && (s.empty() || s.top() > v.back()))
{
break;
}
}
}
if (flag || v.size() == k)
{
break;
}
}
for (int i = 0; i < v.size(); i ++ )
{
if (i != v.size() - 1)
{
cout << v[i] << ' ';
}
else
{
cout << v[i] << endl;
}
}
if(s.empty() && q.empty())
{
break;
}
}
return;
}
int main()
{
cin >> n >> m >> k;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
q.push(x);
}
solve();
return 0;
}
L2-042 老板的作息表
排序 + 模拟
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int n,m;
struct L
{
int hh,mm,ss;
}a[N],b[N];
struct LL
{
int l,r;
}t[N];
bool cmp(struct LL x,struct LL y)
{
if(x.l == y.l )
{
return x.r < y.r;
}
return x.l < y.l;
}
int main()
{
cin >> n;
for(int i = 1 ;i <= n; i ++)
{
scanf("%d:%d:%d - %d:%d:%d",&a[i].hh,&a[i].mm,&a[i].ss,&b[i].hh,&b[i].mm,&b[i].ss);
t[i].l = a[i].hh * 60 * 60 + a[i].mm * 60 + a[i].ss;
t[i].r = b[i].hh * 60 * 60 + b[i].mm * 60 + b[i].ss;
}
t[0] = {0,0};
t[n+1] = {24 * 60 * 60 - 1,24 * 60 * 60 - 1};
sort(t + 1,t + n + 1,cmp);
for(int i = 1; i <= n + 1; i ++)
{
if(t[i].l > t[i - 1].r)
{
printf("%02d:%02d:%02d -",t[i - 1].r / 3600,t[i - 1].r % 3600 / 60,t[i - 1].r % 60);
printf(" %02d:%02d:%02d\n",t[i].l / 3600,t[i].l % 3600 / 60,t[i].l % 60);
}
}
return 0;
}
L2-043 龙龙送外卖
从根节点出发,最短距离d = 走过的路径长度 * 2 - 最大深度
#include<iostream>
#include<cstring>
using namespace std;
const int N = 5e5+10;
int n,m,k;
int fa[N],dep[N];
int dis;
int dfs(int u)
{
if(fa[u] == -1 || dep[u])
{
return dep[u];
}
dis ++;
dep[u] = dfs(fa[u]) + 1;
return dep[u];
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
cin >> fa[i];
}
int d = 0,ans = 0;
for(int i = 1; i <= m; i ++)
{
int t;
cin >> t;
int cnt = dfs(t);
d = max(d,dep[t]);
ans = dis * 2 - d;
cout << ans << endl;
}
return 0;
}
L2-044 大众情人
弗洛伊德最短路径更新最短路径,再更新每个人的异性缘,更新同性内的最大异性缘;
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
int n;
vector<int> ans1,ans2;
int f[510][510];
int ff = 1e9,mm = 1e9;
int dis[N];
char st[N];
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
if(i == j)
f[i][j] = 0;
else
f[i][j] = 1e9;
}
}
for(int i = 1; i <= n; i ++)
{
int t;
char ch;
cin >> ch >> t;
st[i] = ch;
for(int j = 1; j <= t; j ++)
{
int a,b;
scanf("%d:%d",&a,&b);
f[i][a] = b;
}
}
for(int k = 1; k <= n; k ++)
{
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
f[i][j] = min(f[i][j],f[i][k]+f[k][j]);
}
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
if(st[i] != st[j])
{
dis[i] = max(dis[i],f[j][i]);
}
}
}
for(int i = 1; i <= n; i ++)
{
if(st[i] == 'F')
{
ff = min(ff,dis[i]);
}
else
{
mm = min(mm,dis[i]);
}
}
for(int i = 1; i <= n; i ++)
{
if(st[i] == 'F' && dis[i] == ff)
{
ans1.push_back(i);
}
}
for(int i = 1; i <= n; i ++)
{
if(st[i] == 'M' && dis[i] == mm)
{
ans2.push_back(i);
}
}
for(int i = 0; i < ans1.size(); i ++)
{
if(i) cout << " ";
cout << ans1[i];
}
cout << endl;
for(int i = 0; i < ans2.size(); i ++)
{
if(i) cout << " ";
cout << ans2[i];
}
return 0;
}
L3-031 千手观音
拓扑排序,建图很麻烦,具体看代码
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
#include <string>
#include <vector>
using namespace std;
const int N = 1e5 + 10;
int n,m,idx = 1;
int r[N],v[N];
char t[20];
map<string,int> mp1;
map<int,string> mp2;
vector<int> g[N],ans;
string s,ver[N][10];
struct node
{
int x;
friend bool operator < (node a,node b)
{
return mp2[a.x] > mp2[b.x];
}
};
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
scanf("%s",&t);
int la = strlen(t);
for(int j = 0; j < la; j ++)
{
if(t[j] == '.')
v[i] ++;
else
ver[i][v[i]] +=(t[j]);
}
for(int j = 0; j <= v[i]; j ++)
{
if(!mp1[ver[i][j]])
{
mp1[ver[i][j]] = idx;
mp2[idx] = ver[i][j];
idx ++;
}
}
if(i != 1 && v[i] == v[i - 1])
{
for(int j = 0; j <= v[i]; j ++)
{
if(ver[i][j] != ver[i - 1][j])
{
g[mp1[ver[i - 1][j]]].push_back(mp1[ver[i][j]]);
r[mp1[ver[i][j]]] ++;
break;
}
}
}
}
priority_queue<node> q;
for(int i = 1; i < idx; i ++)
{
if(!r[i])
{
q.push({i});
}
}
while(!q.empty())
{
int u = q.top().x;
q.pop();
for(int i = 0; i < g[u].size(); i ++)
{
int v = g[u][i];
r[v] --;
if(!r[v])
{
q.push({v});
}
}
ans.push_back(u);
}
n = ans.size();
for(int i = 0; i < n; i ++)
{
cout << mp2[ans[i]];
if(i < n - 1) cout << ".";
}
return 0;
}
L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事
#include <iostream>
#include <cstring>
#define int long long
using namespace std;
const int N = 3e5 + 10;
const int mod = 1e9 + 7;
int n,m;
int son = 1,ans,er = 500000004;
int e[N * 2],ne[N * 2],h[N * 2],idx;
void add(int a,int b)
{
e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}
int lowbit(int x)
{
return x&(-x);
}
int c[N];
void modify(int x,int k)
{
for(int i = x; i <= n; i += lowbit(i))
{
c[i] += k;
}
}
int quiry(int x)
{
int cnt = 0;
for(int i = x; i ; i -= lowbit(i))
{
cnt += c[i];
}
return cnt;
}
int si[N],dep[N];
void dfs(int u,int f)
{
si[u] = 1;
dep[u] = dep[f] + 1;
int cnt = quiry(n - u + 1);
int x = 1, y = 1;
ans = (ans + cnt) % mod;
modify(n - u + 1,1);
for(int i = h[u]; i != -1; i = ne[i])
{
int v = e[i];
if(v == f)
{
continue;
}
x = x * y % mod;
y ++;
dfs(v,u);
si[u] += si[v];
}
if(x > 1) son = son * x % mod;
modify(n - u + 1, -1);
return;
}
signed main()
{
memset(h,-1,sizeof h);
int root;
cin >> n >> root;
for(int i = 1; i < n; i ++)
{
int a,b;
cin >> a >> b;
add(a,b);
add(b,a);
}
dfs(root,-1);
ans = ans * son % mod;
for(int i = 1; i <= n; i ++)
{
int x = n - dep[i] - si[i] + 1;
ans = (ans + x * son % mod * er % mod * er % mod) % mod;
}
cout << ans << endl;
return 0;
}