题目链接
暂无,作为学校里倒数的队伍,我们参加比赛就是提高自己,本次比赛题目其实很友好,但是我们队伍却不能把握题目的脉络,暴露了极大的问题。
一些题解
A Banana
本题的题意是给定不同的猴子喜欢的不同的香蕉种类,和不同种类的香蕉在不同的地方可以拿到,问猴子可以在那些地方拿到自己喜欢的香蕉。
签到题,队友直接无脑三重循环输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,m;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
bool mon[55][55];
bool place[55][55];
memset(mon,0,sizeof(mon));
memset(place,0,sizeof(place));
int x,y;
int mxm=0,mxp=0,mxb=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
mon[x][y]=1;
mxm=max(mxm,x);
mxb=max(mxb,y);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
place[y][x]=1;
mxp=max(mxp,y);
}
for(int i=1;i<=mxm;i++)
{
for(int j=1;j<=mxp;j++)
{
for(int k=1;k<=mxb;k++)
{
if(mon[i][k]==1&&place[j][k]==1)
{
printf("%d %d\n",i,j);
break;
}
}
}
}
printf("\n");
}
return 0;
}
C Coconut
签到题。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i, s, t) for(int i = s;i <= t;i++)
#define rap(i, s, t) for(int i = s;i >= t;i--)
using namespace std;
int C[1005], D[1005];
int N, b;
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &N, &b);
rep(i, 1, N)
scanf("%d", &C[i]);
rep(i, 1, N - 1)
scanf("%d", &D[i]);
int support = 0;
int flag = 1;
rep(i, 1, N - 1)
{
support += C[i];
support -= D[i] * b;
if(support < 0)
{
flag = 0;
break;
}
}
if(flag == 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
E Half-consecutive Numbers
直接打表题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
LL stan[23] = {
1, 8, 49, 288, 1681, 9800, 57121, 332928, 1940449, 11309768, 65918161, 384199200, 2239277041, 13051463048, 76069501249, 443365544448, 2584123765441, 15061377048200, 87784138523761, 511643454094368, 2982076586042449, 17380816062160328, 101302819786919521};
int main()
{
int t;
scanf("%d", &t);
int kase = 1;
while(t--)
{
LL n;
scanf("%lld", &n);
for(int i = 0;i <= 22;i++)
if(stan[i] >= n)
{
printf("Case #%d: %lld\n", kase++, stan[i]);
break;
}
}
return 0;
}
F Islands
给你一些点的连通情况问你最少需要添加几条边可以让整个图的所有点相互连通。
强连通模板题,直接强连通缩点,记录所缩的点的每个点是否有出度入度,之后分别统计没有出度和没有入度的点的个数,两个数据取大值就是答案。
#include <bits/stdc++.h>
#define MAXN 100010
using namespace std;
vector<int> G[MAXN];
int low[MAXN], dfn[MAXN];
int dfs_clock;
int belong[MAXN], scc_cnt;
vector<int> scc[MAXN];
stack<int> S;
bool Instack[MAXN];
int n, m;
void tarjan(int u, int fa)
{
int v;
low[u] = dfn[u] = ++dfs_clock;
S.push(u);
Instack[u] = true;
for(int i = 0; i < G[u].size(); i++)
{
v = G[u][i];
if(!dfn[v])
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(Instack[v])
low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u])
{
scc_cnt++;
scc[scc_cnt].clear();
while(1)
{
v = S.top(); S.pop();
Instack[v] = false;
belong[v] = scc_cnt;
scc[scc_cnt].push_back(v);
if(v == u) break;
}
}
}
void find_cut(int l, int r)
{
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(belong, 0, sizeof(belong));
memset(Instack, false, sizeof(Instack));
dfs_clock = scc_cnt = 0;
for(int i = l; i <= r; i++)
if(!dfn[i])
tarjan(i, -1);
}
int in[MAXN], out[MAXN];
int main()
{
int tt;
scanf("%d", &tt);
while(tt--)
{
scanf("%d%d", &n, &m);
int s, t;
for(int i = 1; i <= n; i++) G[i].clear();
while(m--)
scanf("%d%d", &s, &t), G[s].push_back(t);
find_cut(1, n);
for(int i = 1; i <= scc_cnt; i++) in[i] = out[i] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < G[i].size(); j++)
{
int u = belong[i];
int v = belong[G[i][j]];
if(u != v)
out[u]++, in[v]++;
}
}
if(scc_cnt == 1)
{
printf("0\n");
continue;
}
int sum_ind = 0, sum_outd = 0;
for(int i = 1; i <= scc_cnt; i++)
{
if(in[i] == 0) sum_ind++;
if(out[i] == 0) sum_outd++;
}
printf("%d\n", max(sum_ind, sum_outd));
}
return 0;
}
H Skiing
题目是说给定一些路径问能连通的最长路径是多少。一开始写了一发搜索t掉了,之后队友开始搞最长路开始各种t各种wa各种段错误,后来我又改进了下搜索的方法,记忆化一下就过去了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i, s, t) for(int i = s;i <= t;i++)
#define rap(i, s, t) for(int i = s;i >= t;i--)
using namespace std;
int N, M;
int node[10005];
struct Edge
{
int v, next, l;
}edge[100005];
int visit[10005];
int dis[10005];
int cnt_edge;
int ans;
int dfs(int u, int val)
{
int sum = 0;
visit[u] = 1;
for(int i = node[u];i != -1;i = edge[i].next)
{
int v = edge[i].v;
if(visit[v] == 1)
sum = max(sum, dis[v] + edge[i].l);
else
{
dfs(v, val + edge[i].l);
sum = max(sum, dis[v] + edge[i].l);
}
}
ans = max(ans, val + sum);
dis[u] = sum;
return sum;
}
void add_edge(int u, int v, int w)
{
edge[cnt_edge].v = v;
edge[cnt_edge].l = w;
edge[cnt_edge].next = node[u];
node[u] = cnt_edge++;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &N, &M);
memset(node, -1, sizeof(node));
memset(visit, 0, sizeof(visit));
memset(dis, 0, sizeof(dis));
cnt_edge = 0;
rep(i, 1, M){
int a, b, l;
scanf("%d%d%d", &a, &b, &l);
add_edge(a, b, l);
}
ans = 0;
rep(i, 1, N){
if(visit[i] == 0)
dfs(i, 0);
}
printf("%d\n", ans);
}
return 0;
}