比赛链接
A.把数存下来然后算一下
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int main() { ios::sync_with_stdio(false); vector<pair<int,int> >v; for(int i=1;i<=9;i++){ int j=i; int k=1; while(j<=10000){ v.pb({j,k}); j=j*10+i; k++; } } int t; for(cin>>t;t;t--){ int x; cin>>x; int ans=0; for(auto k:v){ ans+=k.se; if(k.fi==x){ break; } } cout<<ans<<'\n'; } return 0; }B.找第一个1和最后一个1中间多少个0。比赛的时候写麻烦了。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int t,n,a[N]; int main() { ios::sync_with_stdio(false); for(cin>>t;t;t--){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; int L=-1; for(int i=1;i<=n;i++){ if(a[i]==1) { L = i; break; } } if(L==-1)cout<<0<<'\n'; else{ while(L+1<=n&&a[L+1]==1)L++; if(L==n)cout<<0<<'\n'; else{ int R=-1; for(int i=n;i>=1;i--){ if(a[i]==1){ R=i; break; } } int ans=0; for(int i=L;i<=R;i++)ans+=!a[i]; cout<<ans<<'\n'; } } } return 0; }C.找到一个值最大的数且这个数的两边至少有一个小于最大值。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 3e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int t,n,a[N]; int main() { ios::sync_with_stdio(false); for(cin>>t;t;t--){ cin>>n; int x=0; for(int i=1;i<=n;i++)cin>>a[i],x=max(x,a[i]); int ans=-1; for(int i=1;i<=n;i++){ if(a[i]==x&&(i>1&&a[i]>a[i-1] || i+1<=n&&a[i]>a[i+1])){ ans=i; } } cout<<ans<<'\n'; } return 0; }D.按值排序之后,如果所有数相等肯定无解。 否则全跟第一个数练,跟第一个数相等的跟最后一个连即可。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int t,n,a[N],f[N]; int main() { ios::sync_with_stdio(false); for(cin>>t;t;t--){ cin>>n; for(int i=1;i<=n;i++)cin>>a[i],f[i]=i; sort(f+1,f+1+n,[](int x,int y){return a[x]<a[y];}); if(a[f[1]]==a[f[n]])cout<<"NO\n"; else{ cout<<"YES\n"; for(int i=2;i<=n;i++){ if(a[f[i]]!=a[f[1]]){ cout<<f[i]<<' '<<f[1]<<'\n'; }else{ cout<<f[i]<<' '<<f[n]<<'\n'; } } } } return 0; }E.从n个人中选n/2个放第一批方案是 ( n / 2 n ) (^n_{n/2}) (n/2n),然后n/2个人组成的圆环有 ( n / 2 − 1 ) ! (n/2-1)! (n/2−1)!个。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; LL getpc(LL m, LL n){ LL ans = 1; for (LL k = 1; k <= n; k++){ ans = (ans * (m - n + k)) / k; } return ans; } int n; int main() { ios::sync_with_stdio(false); cin>>n;LL z=1; for(int i=1;i<=n/2-1;i++){ z*=i; } cout<<getpc(n,n/2)*z*z/2; return 0; }F.直接dp i j d表示i行选j个数 和%k=d的最大sum。 注意数组的初始化。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 2e5 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int n,m,k,a[77][77]; int dp[77][77][77],res[77][77],ans[77][77]; int main() { ios::sync_with_stdio(false); cin>>n>>m>>k; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++)cin>>a[i][j]; } int z=m/2; memset(res,-1,sizeof res); for(int j=1;j<=n;j++){ memset(dp,-1,sizeof dp); dp[0][0][0]=0; for(int i=1;i<=m;i++){ for(int d=0;d<=z;d++){ for(int q=0;q<k;q++){ if(d+1<=z&&~dp[i-1][d][q])dp[i][d+1][(q+a[j][i])%k]=max(dp[i-1][d][q]+a[j][i],dp[i][d+1][(q+a[j][i])%k]); if(~dp[i-1][d][q])dp[i][d][q]=max(dp[i][d][q],dp[i-1][d][q]); } for(int q=0;q<k;q++){ res[j][q]=max(res[j][q],dp[i][d][q]); assert(res[j][q]==-1||res[j][q]%k==q); //cout<<j<<' '<<q<<' '<<res[j][q]<<' '<<res[j][q]%k<<endl; } } } } memset(ans,-1,sizeof ans); ans[0][0]=0; for(int i=1;i<=n;i++){ for(int j=0;j<k;j++){ for(int q=0;q<k;q++){ if(~ans[i-1][j] &&~res[i][q])ans[i][(q+j)%k]=max(ans[i][(q+j)%k],ans[i-1][j]+res[i][q]); } for(int q=0;q<k;q++){ if(~ans[i-1][q])ans[i][q]=max(ans[i][q],ans[i-1][q]); } } } cout<<ans[n][0]<<'\n'; return 0; }G.跑n次dij,然后枚举删哪个边即可。 注意最短路可以不经过删的边。
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e3 + 10; #define fi first #define se second #define pb push_back #define wzh(x) cerr<<#x<<'='<<x<<endl; int n,m,k; vector<pair<int,int>>v[N]; int vis[N]; LL res[N]; void gao(int x,int sum,LL *dis){ for(int i=1;i<=sum;i++)vis[i]=0,dis[i]=1e18; dis[x]=0; priority_queue<pair<LL,int>>q; q.push({0,x}); while(!q.empty()){ auto x=q.top(); q.pop(); if(vis[x.se])continue; vis[x.se]=1; for(auto k:v[x.se]){ if(dis[k.fi]>dis[x.se]+k.se){ dis[k.fi]=dis[x.se]+k.se; q.push({-dis[k.fi],k.fi}); } } } } LL dis[N][N],di[N][N]; int L[N],R[N]; struct uzi{ int s,t,w; }; vector<uzi>G; int main() { ios::sync_with_stdio(false); cin>>n>>m>>k; for(int i=1;i<=m;i++){ int s,t,w; cin>>s>>t>>w; v[s].emplace_back(t,w); v[t].emplace_back(s,w); G.pb({s,t,w}); } for(int i=1;i<=k;i++) { cin >> L[i] >> R[i]; if (L[i] == R[i]) continue; gao(L[i], n, res); for(int j=1;j<=n;j++)dis[i][j]=res[j]; gao(R[i], n, res); for(int j=1;j<=n;j++)di[i][j]=res[j]; } LL ans=LLONG_MAX; for(auto t:G){ LL res=0; for(int i=1;i<=k;i++){ res+=min({dis[i][t.s] + di[i][t.t], dis[i][t.t] + di[i][t.s],dis[i][R[i]]}); } ans=min(ans,res); } cout<<ans<<'\n'; return 0; }