第一次写题解,写的不好还请多多包涵
A-acm
原题链接https://vjudge.net/contest/497107#problem/A
这道题是找规律的一道题,因为 是a[i]/i..a[n]/n 所以每个都重复了i次,也就是说原式中为定值1...n求和
所以直接判断总和是否等于k即可
#include<bits/stdc++.h> #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; #define endl "\n" typedef unsigned long long ull; typedef long long ll; const int M=2010; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int N=2e5+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; void solve() { int len,k,s=0; cin>>len>>k; int a[110]; for(int i=1;i<=len;i++) cin>>a[i],s+=a[i]; if(s==k) cout<<"YES"<<endl; else cout<<"NO"<<endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin>>t; while(t--) solve(); return 0; }
B - 实
原题链接https://vjudge.net/contest/497107#problem/B
bfs的一道题需要记录路径
#include<iostream> #include<cstring> #include<vector> #include<queue> #include<algorithm> #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; #define endl "\n" typedef unsigned long long ull; typedef long long ll; const int M=2010; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int N=2e5+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; int a[10][10];bool st[10][10]; vector<PII> ans; PII last[10][10]; void solve() { memset(a,0x3f,sizeof a);//这里是为了使 边界为0x3f3f3f3f不可达 //之所以用base_1 是因为不想特判边界 for(int i=1;i<=5;i++){//读入 for(int j=1;j<=5;j++) cin>>a[i][j]; } queue<PII> q; PII l; l.first=1; l.second=1; q.push(l); st[1][1]=1; while(q.size()){//bfs模板 PII p=q.front();q.pop(); int x=p.first,y=p.second; for(int i=0;i<4;i++){ if(!st[x+dx[i]][y+dy[i]]&&!a[x+dx[i]][y+dy[i]]){//边界是0x3f3f3f3f所以不可达 PII w; w.first=x+dx[i]; w.second=y+dy[i]; st[x+dx[i]][y+dy[i]]=1; last[x+dx[i]][y+dy[i]].first=x; last[x+dx[i]][y+dy[i]].second=y; q.push(w); } } } int x=5,y=5; ans.push_back({x,y}); while(x!=1||y!=1){ PII p=last[x][y]; ans.push_back(p); x=p.first; y=p.second; } reverse(ans.begin(),ans.end());//由于是从后向前录入答案的,所以需要reverse for(int i=0;i<ans.size();i++) cout<<"("<<ans[i].first-1<<", "<<ans[i].second-1<<")"<<endl;//由base_1转为base_0 } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); solve(); return 0; }
C - 验
原题链接https://vjudge.net/contest/497107#problem/C
这道题可以这么想,观察下面的数组
2 1 1 1 1
1 2 1 1 1
1 1 2 1 1
1 1 1 2 1
1 1 1 1 2
这种数组每行每列和都相等,所以我们只要使第1个数满足性质即可
#include<bits/stdc++.h> #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; #define endl "\n" typedef unsigned long long ull; typedef long long ll; const int M=2010; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int N=10000+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; int primes[N],idx;bool st[N]; void init(){//线性筛 st[0]=st[1]=1; for(int i=2;i<=N-10;i++){ if(!st[i]) primes[idx++]=i; for(int j=0;primes[j]*i<=N-10;j++){ st[primes[j]*i]=1; if(i%primes[j]==0) break; } } } int J(int x){ int y=0;//从0开始遇到满足条件的数停止 while(primes[y]<x) y++: while(!st[primes[y]-x]) y++; return primes[y]-x; } void solve() { int len; cin>>len; int z=J(len-1);//因为每行去除了a[i][i],所以剩余的是len-1 for(int i=1;i<=len;i++){ for(int j=1;j<=len;j++){ if(i==j) cout<<z<<" "; else cout<<1<<" "; } cout<<endl; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); init(); int t; cin>>t; while(t--) solve(); return 0; }
D - 室
原题链接https://vjudge.net/contest/497107#problem/D
bfs即可
#include<iostream> #include<queue> #include<vector> #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; #define endl "\n" typedef unsigned long long ull; typedef long long ll; const int M=2010; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int N=100000+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0};//数组开大一点避免RE bool st[N*5];//记录一下 是否已经遍历过 int ans[N*5];//存储答案 queue<PII> q; void solve() { int x,aim; cin>>x>>aim; PII p; p.first=x; p.second=0; q.push(p); st[x+N]=1; while(q.size()&&!st[aim+N]){//bfs p=q.front(); q.pop(); x=p.first; int y=p.second; PII w; if(x+1<=2*N-10&&!st[x+1+N]){//+N是为了避免RE w.first=x+1; w.second=y+1; st[x+1+N]=1; ans[x+1+N]=y+1; q.push(w); } if(x-1>=0&&!st[x-1+N]){ st[x-1+N]=1; w.first=x-1; w.second=y+1; ans[x-1+N]=y+1; q.push(w); } if(x*2<=N*2-20&&!st[x*2+N]){ st[x*2+N]=1; w.first=x*2; w.second=y+1; ans[x*2+N]=y+1; q.push(w); } } cout<<ans[aim+N]; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); return 0; }
J - !!
原题链接https://vjudge.net/contest/497107#problem/J
需要每次选几个数,并使他们等于他们的平均值,使最多人满足>=k
这道题的思路是贪心
每一次在剩余的数中选择最大的数,使他们的平均值大于等于k
这道题可以这么理解若将小的数与大的数相加取平均值,那么会使平均值变小,
我们需要在相同的人数中选择最大的平均值以使其满足条件
此外若直接取平均值会造成精度丢失,所以使用了前缀和+取平均值的想法来写
#include<bits/stdc++.h> #pragma GCC optimize(2) using namespace std; typedef pair<int,int>PII; #define endl "\n" typedef unsigned long long ull; typedef long long ll; const int M=2010; const int INF=0x3f3f3f3f; const int mod=1e9+7; const int N=2e5+10; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; int a[N];ll s[N]; bool cmp(int x,int y){ return x>y; } void solve() { int len,k; cin>>len>>k; for(int i=1;i<=len;i++) cin>>a[i]; sort(a+1,a+len+1,cmp);//从大到小排序 for(int i=1;i<=len;i++) s[i]=s[i-1]+a[i];//求前缀和 int ans=0; while(ans+1<=len&&s[ans+1]/(ans+1)>=k) ans++;//若满足条件则看下一个,需要维护边界使ans<=len cout<<ans<<endl; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin>>t; while(t--) solve(); return 0; }
有些编译器不支持万能头,将头文件改一下即可
5.29训练赛A,B,C,D,J 题解
于 2022-05-29 12:06:58 首次发布