比赛链接: http://www.bnuoj.com/bnuoj/contest_show.php?cid=3907
A. Daka
简单题!时间处理!
# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;
typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>
# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)
struct Time
{
int t, y, m, d;
Time(){};
Time(int aa, int bb, int cc, int dd) : t(aa), y(bb), m(cc), d(dd) {};
};
int One(Time a, Time b)
{
if (a.y == b.y && a.m == b.m && a.d == b.d)
return 1;
return 0;
}
int cmp(const Time &a, const Time &b)
{
if (a.y == b.y)
{
if (a.m == b.m)
{
if (a.d == b.d)
return a.t < b.t;
return a.d < b.d;
}
return a.m < b.m;
}
return a.y < b.y;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i, j, k, l, h, m, s, t, yy, mm, dd;
int f1, f2, c1, c2, t1, t2;
int l1 = 7 * 3600, r1 = 8 * 3600 + 30 * 60;
int l2 = 16 * 3600, r2 = 21 * 3600 + 30 * 60;
int half = 30 * 60;
vector<Time> u;
c1 = c2 = 0; //morning / half
while (scanf ("%d %d %d %d %d %d", &h, &m, &s, &yy, &mm, &dd) != EOF)
{
t = h * 3600 + m * 60 + s;
u.pb(Time(t, yy, mm, dd));
}
sort (all(u), cmp);
for (i = 0; i < sz(u); i++)
{
j = i;
while (j < sz(u) && One(u[i], u[j]))
j++;
f1 = f2 = 0;
for (k = i; k < j; k++)
{
int t1 = u[k].t;
if (t1 >= l1 && t1 <= r1) f1 = 1;
}
t1 = u[i].t, t2 = u[j - 1].t;
if (min (t2, r2) - max (t1, l2) >= half)
f2 = 1;
c1 += f1, c2 += f2;
i = j - 1;
}
printf ("%d %d\n", 10 - min (10, c1), 20 - min (20, c2));
return 0;
}
蛮好的题!倍增法求lca
如果lca(x, y) != y, 答案就是y的父节点!
否则通过从x 节点2分查找深度为dep[y] + 1的节点就是答案!
# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;
typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>
# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)
# define N 10005
# define M 20005
const int POW = 18;
int father[N];
int p[N][20], dep[N];
int num, head[N];
struct edge
{
int u, v, next;
}e[M];
void addedge(int u, int v)
{
e[num].u = u;
e[num].v = v;
e[num].next = head[u];
head[u] = num++;
}
void dfs(int u, int fa)
{
int i, v;
father[u] = fa;
dep[u] = dep[fa] + 1;
p[u][0] = fa;
for (i = 1; i < POW; i++)
p[u][i] = p[p[u][i - 1]][i - 1];
for (i = head[u]; i != -1; i = e[i].next)
{
v = e[i].v;
if (v == fa) continue;
dfs(v, u);
}
}
int lca(int a, int b)
{
int i, d;
if (dep[a] > dep[b]) swap(a, b);
if (dep[a] < dep[b]) //调整深度
{
d = dep[b] - dep[a];
for (i = 0; i < POW; i++)
if (d & (1 << i))
b = p[b][i];
}
if (a != b)
{
for (i = POW - 1; i >= 0; i--)
if (p[a][i] != p[b][i])
a = p[a][i], b = p[b][i];
a = p[a][0], b = p[b][0];
}
return a;
}
void init()
{
num = 0;
mem (head, -1);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T, i, j, n, m, u, v, x, y, d;
scanf ("%d", &T);
while (T--)
{
init();
scanf ("%d %d", &n, &m);
for (i = 1; i < n; i++)
{
scanf ("%d %d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs(1, 0);
for (i = 1; i <= m; i++)
{
scanf ("%d %d", &x, &y);
if (lca(x, y) != y)
printf ("%d\n", father[y]);
else
{
if (father[x] == y)
printf ("%d\n", x);
else //2分查找
{
d = dep[x] - dep[y] - 1;
for (j = 0; j < POW; j++)
if (d & (1 << j))
x = p[x][j];
printf ("%d\n", x);
}
}
}
}
return 0;
}
枚举每一个字符串的每一位, 分别替换成其他25个字母! 替换完后的字符串如果存在就构建一条边!
构完图后跑一遍最短路就可以了!
# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;
typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>
# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)
# define N 6005
map<string, int> Hash;
char s[N];
VI edge[N];
int dis[N], vis[N], n;
int spfa(int s, int t)
{
int i, u, v;
queue<int> q;
for (i = 1; i <= n; i++)
dis[i] = INF;
dis[s] = 0, vis[s] = 1;
q.push(s);
while (!q.empty())
{
u = q.front();
q.pop();
for (i = 0; i <sz(edge[u]); i++)
{
v = edge[u][i];
if (dis[u] + 1 < dis[v])
{
dis[v] = dis[u] + 1;
if (!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
vis[u] = 0;
}
return dis[t];
}
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i, j, k, u, v;
vector<string> S;
n = 0;
while (scanf ("%s", s) != EOF)
{
if (!Hash[s]) Hash[s] = ++n;
S.pb(s);
}
for (i = 0; i < sz(S); i++)
{
// cout << s << Hash[s] << endl;
string s = S[i];
for (j = 0; j < sz(s); j++)
for (k = 0; k < 26; k++)
if (s[j] - 'a' != k)
{
string ts = s;
ts = ts.replace(j, 1, 1, 'a' + k);
if (Hash[ts])
{
u = Hash[S[i]], v = Hash[ts];
if (u != v)
// printf ("%d -> %d\n", u, v);
edge[u].pb(v);
}
}
}
int ans = spfa(1, 2);
if (ans == INF)
printf ("-1\n");
else
printf ("%d\n", ans + 1);
return 0;
}
D.//O(n^3)DP + floyd 待补
E.//不会
F.//找规律+矩阵,待补
G.//据说是费用流,待补
H.Selecting World Finals Teams on Mars I
简单题, DFS! 每个节点保存最大和次大,从叶子往上更新即可!
# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;
typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>
# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)
# define N 20005
# define M 30005
char s[N][105];
int w[N];
int fir[N], sec[N];
int num, head[N];
int Hash[N];
struct edge
{
int u, v, next;
}e[M];
void addedge(int u, int v)
{
e[num].u = u;
e[num].v = v;
e[num].next = head[u];
head[u] = num++;
}
int dfs(int u, int fa)
{
int i, v;
if (w[u]) fir[u] = w[u];
for (i = head[u]; i != -1; i = e[i].next)
{
v = e[i].v;
if (v == fa) continue;
dfs(v, u);
if (fir[v] > fir[u])
{
sec[u] = fir[u];
fir[u] = fir[v];
if (sec[v] > sec[u])
sec[u] = sec[v];
}
else if (fir[v] > sec[u])
sec[u] = fir[v];
}
}
void init()
{
num = 0;
mem (head, -1);
}
int cmp(int a, int b)
{
return w[a] > w[b];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i, n, m, u, v;
VI ans;
while (scanf ("%d %d", &n, &m) != EOF)
{
init();
clr (ans);
mem (w, 0);
mem (fir, 0);
mem (sec, 0);
mem (Hash, 0);
for (i = 1; i < n + m; i++)
{
scanf ("%d %d", &u, &v);
addedge(u, v);
addedge(v, u);
}
for (i = n + 1; i <= n + m; i++)
scanf ("%s %d", s[i], &w[i]);
dfs(1, 0);
// printf ("*******************\n");
// for (i = 1; i <= n + m; i++)
// printf ("%d : %d %d\n", i, fir[i], sec[i]);
// printf ("*******************\n");
for (i = head[1]; i != -1; i = e[i].next)
{
v = e[i].v;
if (fir[v] != 0) Hash[fir[v]] = 1;
if (sec[v] != 0) Hash[sec[v]] = 1;
// printf ("%d : %d %d\n", v, fir[v], sec[v]);
}
for (i = n + 1; i <= n + m; i++)
if (Hash[w[i]])
ans.pb(i);
sort (all(ans), cmp);
for (i = 0; i < sz(ans); i++)
printf ("%s\n", s[ans[i]]);
}
return 0;
}
I.//不会
J.Selecting World Finals Teams on Mars II
蛮好的题, 线段树! 按3个键值分别从小到大排序, 每次找小于第2个键值中第3个键值最小的值,如果最小值小于这个3元组的第3个键值, 则这个3元组不计数!
否则Count++, 输出Count即可!
# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;
typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>
# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)
# define N 100005
# define M 105
int Min[M << 2];
struct node
{
int a, b, c;
}e[N];
void PushUp(int rt)
{
Min[rt] = min (Min[rt << 1], Min[rt << 1 | 1]);
}
void Update(int pos, int x, int l, int r, int rt)
{
int m;
if (l == r)
{
Min[rt] = min (Min[rt], x);
return;
}
m = (l + r) >> 1;
if (pos <= m) Update(pos, x, lson);
else Update(pos, x, rson);
PushUp(rt);
}
int Query(int L, int R, int l, int r, int rt)
{
int ans = INF, m;
if (L <= l && R >= r)
return Min[rt];
m = (l + r) >> 1;
if (L <= m) ans = min (ans, Query(L, R, lson));
if (R > m) ans = min (ans, Query(L, R, rson));
return ans;
}
int cmp(const node &a, const node &b)
{
if (a.a == b.a)
{
if (a.b == b.b)
return a.c < b.c;
return a.b < b.b;
}
return a.a < b.a;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i, j, k, n, ans;
while (scanf ("%d", &n) != EOF)
{
ans = n;
fill(Min, Min + 400, INF);
for (i = 1; i <= n; i++)
scanf ("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
sort (e + 1, e + n + 1, cmp);
for (i = 1; i <= n; i++)
{
j = i;
while (j <= n && e[j].a == e[i].a)
j++;
for (k = i; k < j; k++)
{
if (e[k].b == 1) continue;
if (Query(1, e[k].b - 1, 1, 100, 1) < e[k].c)
ans--;
}
for (k = i; k < j; k++)
Update(e[k].b, e[k].c, 1, 100, 1);
i = j - 1;
}
printf ("%d\n", ans);
}
return 0;
}
