比赛打到一半了,莫名有一种对未来的慌张,时间都过去一半了,还没有特别大的能力上的突破。这场比赛也是在拼罚时,最后一题和队友同时想到算法,很快ac。T6和T8出的太慢了,导致我们罚时输了很多很多。能切几题确实很重要,但是目前更大的问题反而是我们队的罚时,这点很致命。
1006 Rikka with Graph
考虑贪心地一条一条边添加进去。
当 m≤n−1 时,我们需要最小化距离为 n 的点对数,所以肯定是连出一个大小为 m+1 的联通块,剩下的点都是孤立点。在这个联通块中,为了最小化内部的距离和,肯定是连成一个菊花的形状,即一个点和剩下所有点直接相邻。
当 m>n−1 时,肯定先用最开始 n−1 条边连成一个菊花,这时任意两点之间距离的最大值是 2。因此剩下的每一条边唯一的作用就是将一对点的距离缩减为 1。
这样我们就能知道了最终图的形状了,稍加计算就能得到答案。要注意 m 有可能大于 2n(n−1)。
#include "stdio.h" #include "iostream" #include "cstring" using namespace std; typedef long long ll; int main(int argc, char const *argv[]) { int t; while(cin>>t) { while(t--) { ll n,m; cin>>n>>m; ll ans=0; if(m*2>=(n*n-n)) { ans=n*n-n; } else if(m>=n-1) { ans=2*n*(n-1)-2*m; }else{ ans=n*n*n-n*n-(m*m+m)*n+2*m*m; } cout<<ans<<endl; } } return 0; }
1008 Rikka with Subset
签到题,大致的思想就是反过来的背包。
如果 Bi 是 B 数组中除了 B0 以外第一个值不为 0 的位置,那么显然 i 就是 A 中的最小数。
现在需要求出删掉 i 后的 B 数组,过程大概是反向的背包,即从小到大让 Bj−=Bj−i。
时间复杂度 O(nm)。
#include<bits/stdc++.h> using namespace std; int n,m; int a[10005],ans[10005],S[10005],tmp[10005]; int main() { int T; cin>>T; while (T--) { scanf("%d%d",&n,&m); for (int i=0;i<=m;i++) scanf("%d",a+i); memset(S,0,sizeof(S)); S[0]=1; int top=0; for (int i=0;i<=m;i++) { while (S[i]<a[i]) { memcpy(tmp,S,sizeof(S)); for (int j=0;j<=m;j++) { if (tmp[j]==0) continue; S[i+j]+=tmp[j]; } top++; ans[top]=i; } if (top>=n) break; } for (int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
1011 Rikka with Competition
临时加的签到题。把 ai 从大到小排序,那么第 i 强人要获胜,最优情况下是最强的人输给了第二强的人,第二强的人输给了第三强的人,以此类推。因此只需要判断排序后 maxj<i(aj−aj+1) 和 K 的大小关系即可。
时间复杂度 O(nlogn)。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <stack> #include <string> using namespace std; typedef long long ll; const int MAXN=100100; int arr[MAXN]; int main(int argc, char const *argv[]) { //freopen("input.txt","r",stdin); int t; cin>>t; while(t--) { int n,k; cin>>n>>k; for(int i=0;i<n;++i) scanf("%d",&arr[i]); sort(arr,arr+n); int ans=1; for (int i = n-1; i > 0; --i) { if(arr[i]-arr[i-1]<=k) ans++; else break; } cout<<ans<<endl; } return 0; }