5.29训练赛A,B,C,D,J 题解

第一次写题解,写的不好还请多多包涵

A-acm

B - 实

C - 验

D - 室

J - !!


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;
}

有些编译器不支持万能头,将头文件改一下即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值