有n个盒子,第i个盒子初始有ai个物品,每一天你可以把某个盒子的一个物品移动到相邻盒子里,求d天之后第一个盒子最多有多少个物品
简单题,直接模拟即可,详细见代码。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 5e4+5; int num[maxn]; int main() { int T; scanf("%d",&T); while(T--) { int n,d; scanf("%d %d",&n,&d); for(int i = 1;i<=n;++i) scanf("%d",&num[i]); for(int i =2;i<=n;++i) { int cost = i-1; int tmp = d/cost; tmp = min(tmp,num[i]); num[1]+=tmp; num[i]-=tmp; d-=tmp*cost; if(num[i]>0) break; } cout << num[1]<< "\n"; } return 0; }
给你一个位于x轴上的点k,以及m个你-次能走的距离,求从原点出发,你最少走几次能到达k点,输出次数。
首先,如果可以一步走到的话只需要走一步,假如一步走不到的话,设他所能走的最大步数是max,我们首先水平向右走到距离小于等于2*max,然后最后的一点距离一定可以用两步max斜着走来实现。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 1e5+5; LL num[maxn]; set<LL> s; int main() { int T; scanf("%d",&T); while(T--) { s.clear(); LL n,x; cin >> n >>x; LL ma = 0; LL ans = 0; for(int i =1;i<=n;++i ) { cin >> num[i]; s.insert(num[i]); ma =max(ma,num[i]); } // LL ans = 0; // cout << "ma = " << ma << "\n"; if(s.find(x)!=s.end()) { ans = 1; } else { if(x<=2*ma) ans = 2; else { ans = x/ma; if(x%ma) ++ans; } } cout << ans << "\n"; } return 0; }
给你一个字符串,求某个子序列出现的最大次数,子序列中的相邻元素在原串中的距离一定相同,输出出现的最大次数。
可以知道的是,最优解解只能从长度为1的子序列以及长度为2的子序列中选取,基于这个条件,我们就很容易得出这个题的思路。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 1e5+5; LL cnt[30],c2[30],num[30][30]; int main() { string s; cin >> s; int len = s.size(); LL ans = 0; for(int i = 0;i<len;++i) ++cnt[s[i]-‘a‘]; for(int i = 0;i<26;++i) ans = max(ans,cnt[i]); for(int i = 0;i<len;++i) { // c2[s[i]-‘a‘]++; cnt[s[i]-‘a‘]--; for(int j = 0;j<26;++j) { num[s[i]-‘a‘][j]+=cnt[j]; } } for(int i = 0;i<26;++i) { for(int j = 0;j<26;++j) ans = max(ans,num[i][j]); } cout << ans << "\n"; return 0; }
给定一个有n个顶点的树,其中有k个特殊顶点,,你必须且只能在选择两个特殊点连接一条边,使得从1-n的最短路最大,输出最短路的长度。
对于一个特殊点p来说,我们定义他到1的距离是f(p),他到n的距离是g(p),现在我们假设选择建边的两个点是下x,y,那么1-n的路径有两种可能。
第一种是1-x,x-y,y-n,路径长度为f(x)+1+g(y);
第二种是1-y,y-x,x-n,路径长度为f(y)+1+g(x);
为了方便计算,我们把第一种认为是最优的,则应该有 f(x)+1+g(y)>=f(y)+1+g(x),则有f(x)-g(x)>=f(y)-g(y)。
如果我们依照上面的规则排个序,则最优路径的选择一定是第二种情况(因为在两条路径都存在时要取较小的那一条)。这是,对于路径长度f(x)+1+g(y),我们只需要找到最大的f(x),以及最大的g(y)即可。
要注意的是,在上面的讨论中我么们只是考虑了它一定走这条新建边的情况,所以最后求出的答案还要跟原先的最短路取个最小值。
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5+7; int n,m,k; vector<int>G[maxn]; int dis[2][maxn],a[maxn],vis[maxn]; void bfs(int x,int st) { memset(vis,0,sizeof(vis)); for(int i = 1;i<=n;++i) dis[x][i] = 1e9; queue<int>Q; dis[x][st] = 0; vis[st] = 1; Q.push(st); while(!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0;i<G[now].size();++i) { int nxt = G[now][i]; if(vis[nxt]) continue; dis[x][nxt] = dis[x][now]+1; Q.push(nxt); vis[nxt] = 1; } } } int main() { cin >> n >> m >> k; for(int i = 0;i<k;++i) cin >> a[i]; for(int i =0;i<m;++i) { int x,y; cin >> x>> y; G[x].push_back(y); G[y].push_back(x); } bfs(0,1); bfs(1,n); int ans = 0; vector<pair<int,int> >V; for(int i = 0;i<k;++i) { V.push_back(make_pair(dis[0][a[i]]-dis[1][a[i]],a[i])); } sort(V.begin(),V.end()); int tmp = 0; for(int i = 0;i<V.size();++i) { if(i!=0) { ans = max(ans,tmp+dis[1][V[i].second]+1); } tmp = max(tmp,dis[0][V[i].second]); } cout << min(ans,dis[0][n]) << "\n"; return 0; }
Codeforces Round #621 (Div. 1 + Div. 2)
原文:https://www.cnblogs.com/baihualiaoluan/p/12457813.html