0
点赞
收藏
分享

微信扫一扫

2022年寒假训练赛第5场

mafa1993 2022-02-13 阅读 65

A:三英战吕布

题目描述

输入

输出

  • 思维题
  • 求出点算距离就行
#include<bits/stdc++.h>
using namespace std;
#define ll long long
double a[5],b[5];
int main(){
    for(int i=1;i<=4;i++)
        scanf("%lf%lf",&a[i],&b[i]);
    double x=(a[1]+a[2]+a[3])/3.0;
    double y=(b[1]+b[2]+b[3])/3.0;
    printf("%.2f\n",sqrt((a[4]-x)*(a[4]-x)+(b[4]-y)*(b[4]-y)));
    return 0;
}

B: a碟求最大值

题目描述

输入

输出

  • 求最大值则 i * j 要尽可能大,可以从后往前枚举 i * j ,然后当枚举到 i * j 已经小于找到的最大值时,就可以跳出循环,节省时间
  • 注意一个细节,如果定义i 和 j 是int类型的话,i * j 要强制类型转换,不然会丢失精度
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[100005];
int n,k;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        ll ans=-INF;
        for(int i=n-1;i>=1;--i){
            if((ll)i*n<=ans)break;//现在i*j已经小于找到的最大值,再往前枚举也只能比现在更小
            for(int j=n;j>i;--j){
                ll d=(ll)i*j-(ll)k*(a[i]|a[j]);//强转
                ans=max(ans,d);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

C: 超级小分队

题目描述

输入

输出

  • 数组b保存前n项和,枚举找出最大的m个数之和就行,比较水
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[1005],b[1005];
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=b[i-1]+a[i];
    }
    int ans=0;
    for(int i=m;i<=n;i++){
        ans=max(ans,b[i]-b[i-m]);
    }
    printf("%.2f\n",1.0*ans/m);
    return 0;
}

D: X星人的宝藏

题目描述

输入

输出

  • 动态规划
  • dp[ i ][ j ]表示到第 i 个点时气球已经启动 j 次
  • dp[ i ][ j ]该状态可由 i 之前的且距离小于等于m的某个位置 l 转移过来
  • 状态转移方程 dp[ i ][ j ]=max(dp[ i ][ j ],dp[ l ][ j-1 ]+b[ i ]);
#include <bits/stdc++.h>
using namespace std;
#define ll  long long
int n,m,k;
int ans;
int a[105],b[105];
int dp[105][105];
int main(){
 
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i],&b[i]);
    memset(dp,-0x3f,sizeof(dp));
    dp[1][0]=b[1];
    for(int i=2;i<=n;i++)
    for(int j=1;j<=k;j++){
        for(int l=i-1;l>=1;l--){
            if(m>=a[i]-a[l]){
                dp[i][j]=max(dp[i][j],dp[l][j-1]+b[i]);
            }
            else break;
        }
        ans=max(ans,dp[i][j]);
    }
    printf("%d\n",ans);
    return 0;
}

E: 神奇的口袋

题目描述

输入

输出

  • 动态规划水题
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a[50];
int dp[50];
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    dp[0]=1;
    for(int i=1;i<=n;i++)
        for(int j=40;j>=a[i];j--)
            dp[j]+=dp[j-a[i]];
    printf("%d\n",dp[40]);
    return 0;
}

F: 找出直系亲属

题目描述

输入

输出

  • 方法1:直接模拟,map记录每一对父母关系,例如mp[a]=b 则a的儿子是b,然后对询问找出所有的可能模拟就行
  • 方法2:搜索,就不用找出所有可能,直接搜索,最终搜到了就是有关系,然后根据要求输出就行
  • 这题的字符不要单个字符单个字符输入,直接字符串输入一行会节省很多时间
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int n,m;
map<char,char>mp;
void ask(char a,char b){
    if(!mp[a]&&!mp[b]){
        puts("-");
    }
    else if(mp[a]==b){
        puts("parent");
    }
    else if(mp[b]==a){
        puts("child");
    }
    else if(mp[mp[a]]==b){
        puts("grandparent");
    }
    else if(mp[mp[b]]==a){
        puts("grandchild");
    }
    else {
        int ans=0;
        char c=a;
        while(mp[c]&&mp[c]!=b){
            c=mp[c];
            ans++;
        }
        if(mp[c]==b){
            while(ans>=2){
                ans--;
                printf("great-");
            }
            puts("grandparent");
            return ;
        }
 
        ans=0;
        c=b;
        while(mp[c]&&mp[c]!=a){
            c=mp[c];
            ans++;
        }
        if(mp[c]==a){
            while(ans>=2){
                ans--;
                printf("great-");
            }
            puts("grandchild");
            return ;
        }
 
        puts("-");
    }
}
int dfs(int be,int la,int ans){
    if(be==la)return ans;
    if(isalpha(mp[be])) return dfs(mp[be],la,ans+1);
    return -1;
}
int main(){
    char s[5];
    while(~scanf("%d%d",&n,&m)){
        mp.clear();
        while(n--){
            scanf("%s",s);
            if(s[1]!='-')mp[s[1]]=s[0];
            if(s[2]!='-')mp[s[2]]=s[0];
        }
        while(m--){
            scanf("%s",s);
            //ask(s[0],s[1]);//直接模拟
            int ans=dfs(s[1],s[0],0);//搜索
            if(ans!=-1){
                for(int i=3;i<=ans;++i) printf("great-");
                if(ans>=2) printf("grand");
                puts("child");
                continue;
            }
            ans=dfs(s[0],s[1],0);
            if(ans!=-1){
                for(int i=3;i<=ans;++i) printf("great-");
                if(ans>=2) printf("grand");
                puts("parent");
                continue;
            }
            puts("-");
        }
    }
    return 0;
}

G: 最小长方形

题目描述

输入

输出

  • 水题
  • 左下角坐标(最小的x,最小的y),右上角坐标(最大的x,最大的y)
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int a,b,c,d;
int x,y;
int main(){
 
    while(scanf("%d%d",&a,&b)&&(a+b)){
        c=a;
        d=b;
        while(scanf("%d%d",&x,&y)&&(x+y)){
            a=min(a,x);
            b=min(b,y);
            c=max(c,x);
            d=max(d,y);
        }
        printf("%d %d %d %d\n",a,b,c,d);
    }
    return 0;
}

H: 逆序五进制

题目描述

输入

输出

  • 水题
#include<bits/stdc++.h>
using namespace std;
int n,m;
void turn(){
    string s="";
    while(m){
        s+=to_string(m%5);
        m/=5;
    }
    reverse(s.begin(),s.end());
    cout<<s<<endl;
}
int main(){
    cin>>n;
    while(n){
        m=m*10+n%10;
        n/=10;
    }
    turn();
    return 0;
}

I: XP的魔塔

题目描述

输入

输出

  • 搜索
  • 就是普通的搜索,没什么难度…
  • 下面给出dfs和bfs两种方法
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
int n;
bool flag;
int di[][2]={0,1,1,0,0,-1,-1,0};
int vis[105][105];
char a[105][105];
int b[105][105];
int dx,dy;
bool check(int x,int y){
    if(x>=1&&x<=n&&y>=1&&y<=n&&a[x][y]!='X')
        return 1;
    return 0;
}
void dfs(int x,int y,int ans){
    if(a[x][y]=='T'||flag){
        flag=1;
        return ;
    }
    for(int i=0;i<4;i++){
        int xx=x+di[i][0];
        int yy=y+di[i][1];
        if(check(xx,yy)&&!vis[xx][yy]&&ans>b[xx][yy]){
                vis[xx][yy]=1;
                dfs(xx,yy,ans-b[xx][yy]);
            }
        }
}
struct node{
    int x,y;
    int ans;
    bool operator<(const node &q)const{
        return ans<q.ans;
    }
};
void bfs(){
    priority_queue<node>q;
    q.push({dx,dy,b[dx][dy]});
    while(!q.empty()){
        node k=q.top();
        q.pop();
        if(a[k.x][k.y]=='T'){
            flag=1;
            return ;
        }
        vis[k.x][k.y]=1;
        for(int i=0;i<4;i++){
            int xx=k.x+di[i][0];
            int yy=k.y+di[i][1];
            if(check(xx,yy)&&k.ans>b[xx][yy]&&!vis[xx][yy]){
                q.push({xx,yy,k.ans-b[xx][yy]});
            }
        }
    }
}
int main(){

    int t;
    scanf("%d",&t);
    while(t--){
        memset(vis,0,sizeof(vis));
        flag=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",a[i]+1);
            for(int j=1;j<=n;j++)
                if(a[i][j]=='S'){
                dx=i;
                dy=j;
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&b[i][j]);
        dfs(dx,dy,b[dx][dy]);
        //bfs();
        if(flag)puts("YES");
        else puts("NO");
    }
    return 0;
}
举报

相关推荐

0 条评论