A.
题意:有1~n一排数,每天可以搬运一个东西到相邻的位置,一共搬运d天,问你1号位置最多能有多少东西
题解:肯定是贪心往1号位置搬,先从2号位置搬,再从3号位置搬,一直搬到到达第d天或者全部搬完为止
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, a[N];
void solve()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
int num = min(a[i],m/i);
a[0]+=num;
m-=num*i;
}
printf("%d\n",a[0]);
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
}
B.
题意:一个人要从(0,0)走到(x,0),但是每次只能走他喜欢的步数,他有n个喜欢的步长,你每次可以选择其中的一种,问你他走到(x,0)最少需要几步。
题解:分析可以发现除了x恰好等于其中一个喜欢的步数答案为1以外,其他都可以通过选择最大的步长走到,并且答案是最优的,如果x%最长的步数恰好为0那么就一直直走;否则前面直走,走到小于2倍步长斜着走即可。
就是对x向上取整
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, x, a[N];
map<int,int>H;
void solve()
{
H.clear();
scanf("%d%d",&n,&x);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
H[a[i]]=1;
}
sort(a,a+n);
if(H[x])
puts("1");
else
printf("%d\n",max(2,(x+a[n-1]-1)/a[n-1]));
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
}
C.
题意:给你一个s序列,定义序列t,t满足为s的子序列,并且t的每一位下标在s中构成等差序列。询问在所有的t中,哪种序列出现次数最多。
题解:发现每增加一位都会增加一些限制,这样序列个数肯定不会多,所以我要考虑限制最少的。限制最少的肯定是仅由1个或2个字符组成的,没有任何限制,我们就找这两种就好了。单个的序列我们在遍历的时候更新即可,两个组成的序列,我们在遍历的时候用dp[i][j]记录,表示以i为开头,以字符j结尾的序列次数
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
ll a[30], dp[30][30];
int main()
{
string s;
cin >> s;
ll ans = 0;
for (int i = 0; i < s.length(); i++)
{
for (int j = 0; j < 26; j++)
{
dp[j][s[i] - 'a'] += a[j];
ans = max(ans, dp[j][s[i] - 'a']);
}
a[s[i] - 'a']++;
ans = max(ans, a[s[i] - 'a']);
}
printf("%lld\n", ans);
return 0;
}D.
题意:一共有n个点和m条边,有k个特殊点,要求从中选取两个建一条边使得从1到n的最短路最大
题解:设ax为1号点到k个节点中的一个节点x的最短路径,by为n号节点到k个节点中的另一个节点y的最短路径,1号节点通过x、y路径到n的距离为ax+by+1。那么交换x、y以后,距离为ay+bx+1,要求最短路,如果是答案那么只会是min(ax+by+1,ay+bx+1),我们令ax+by+1<ay+bx+1,消掉1,交换ay和by得,ax-ay<bx-by,由此我们可以对(ax-ay)进行排序,对于每一个ax之后的每一个by都是满足ax+by<ay+bx,即为可能的答案,算出其中的最大值与不加边的最短路比较取小着即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> pii;
int a[maxn], dis[2][maxn];
vector<int> G[maxn];
void bfs(int st, int idx)
{
dis[idx][st] = 0;
queue<int> q;
q.push(st);
while (!q.empty())
{
int u = q.front();
q.pop();
for (auto v : G[u])
if (dis[idx][v] == INF)
{
dis[idx][v] = dis[idx][u] + 1;
q.push(v);
}
}
}
int main()
{
memset(dis, INF, sizeof(dis));
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < k; i++)
scanf("%d", &a[i]);
sort(a, a + k);
for (int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
bfs(1, 0);
bfs(n, 1);
vector<pii> v;
for (int i = 0; i < k; i++)
v.emplace_back(dis[0][a[i]] - dis[1][a[i]], a[i]);
sort(v.begin(), v.end());
int ans = 0, tmp = 0;
for (int i = 0; i < v.size(); i++)
{
if (i)
ans = max(ans, tmp + dis[1][v[i].second] + 1);
tmp = max(tmp, dis[0][v[i].second]);
}
cout << min(dis[0][n], ans) << endl;
return 0;
}
京公网安备 11010502036488号