第十一届山东省大学生程序设计竞赛

D.Dyson Box

题意:给n个盒子所在位置,对每个盒子都有两种重力,如果重力方向是水平的,所有物体都会水平向左移动,垂直的则会使所有立方体向下移动。给每出一行盒子位置,输出向下和向左后的盒子周长。

题解:如果重力是水平方向,盒子都会向左;先假设每行都不相邻,一行上有一个盒子周长是4,每次增加一个盒子周长+2;再判断盒子上下行是否有相邻,如果有依次-2。垂直方向同理,

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAXN 200010
int a[MAXN],b[MAXN];
int main(){
    int n;
    cin>>n;
    int x,y;
    ll sum1=0,sum2=0;
    for(int i=1;i<=n;i++){
        cin>>x>>y;
        a[x]++;
        b[y]++;
        if(a[x]==1){
            sum1+=4;
        }else{
            sum1+=2;
        }
        if(a[x-1]>=a[x]){
            sum1-=2;
        }
        if(a[x+1]>=a[x]){
            sum1-=2;
        }
        if(b[y]==1){
            sum2+=4;
        }else{
            sum2+=2;
        }
        if(b[y-1]>=b[y]){
            sum2-=2;
        }
        if(b[y+1]>=b[y]){
            sum2-=2;
        }
        cout<<sum1<<" "<<sum2<<endl;
    }
    return 0;
}
View Code

F.Birthday Cake

 

 

G.Grade Point Average

题意:输出n个数的平均值,保留前k位小数

题解:模拟除法过程

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int n,k,a;
    cin>>n>>k;
    ll sum=0,yu=0;
    for(int i=1;i<=n;i++){
        cin>>a;
        sum+=a;
    }
    cout<<sum/n<<".";
    yu=sum%n;
    while(k--){
        yu=yu*10;
        cout<<yu/n;
        yu=yu%n;
    }
    cout<<endl;
    return 0;
} 
View Code

H.Adventurer's Guild

题意:Yuna的生命力为H,耐力为S;他的生命力下降到0他会死,但当他的耐力下降到不足为0时他不会放弃,当耐力不足时,从生命力消减他的耐力。给出n个怪物和消灭每个怪物所需要的生命力、耐力以及Yuna能获得金币,求能获得的最大金币数。

题解:DP,寻找状态转移方程;dp[i][k],i为生命力,k为耐力。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
  ll h;
  ll s;
  ll w;
}a[1100];
ll dp[310][310];
int main(){
    ll i,j,n,k,hh,ss;
    cin>>n>>hh>>ss;
    for(i=1;i<=n;i++){
        cin>>a[i].h>>a[i].s>>a[i].w;
    }
    for(i=1;i<=n;i++){
        for(j=hh;j>0;j--){
            for(k=ss;k>=0;k--){
                if(j>a[i].h&&k>=a[i].s){
                    dp[j][k]=max(dp[j][k],dp[j-a[i].h][k-a[i].s]+a[i].w);
                }else if(k<a[i].s&&a[i].h+a[i].s<j+k){
                    dp[j][k]=max(dp[j][k],dp[j-a[i].s-a[i].h+k][0]+a[i].w);
                }
            }
        }
    }
    cout<<dp[hh][ss]<<endl;
    return 0;
}
View Code

M.Matrix Problem

题意:题意也太难懂了。给定0/1矩阵C ,构造两个矩阵A,B ,其中1形成了完整的不分散的一块四连通块,并且对于C中所有位置,若是 1,则A,B对应位置必须都是 ,否则A,B 之中必须有一个这个位置为 0。 保证C阵的边框都是0 。(四连通块的意思大概是这样吧:每个1能通过四连通的走法(上下左右),只走1,到达该联通块中的其它1。)

题解:边框都是0:使A矩阵最左侧一列为0,最右侧一列为1,奇数行为0,偶数行为1;使B矩阵最左侧一列为1,最右侧一列为0,奇数行为1,偶数行为0;c[i][j]为1的地方为1,那么AB矩阵相应位置为1;

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define MAXN 510
int c[MAXN][MAXN];
int main(){
    int n,m;
    cin>>n>>m;
    char s;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>s;
            c[i][j]=s-'0';
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(j==m){
                cout<<0;
            }else if(j==1){
                cout<<1;
            }else if(c[i][j]==1){
                cout<<1;
            }else{
                if(i&1){
                    cout<<0;
                }else{
                    cout<<1;
                }
            }
        }
        cout<<endl;
    }
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(j==m){
                cout<<1;
            }else if(j==1){
                cout<<0;
            }else if(c[i][j]==1){
                cout<<1;
            }else{
                if(i&1){
                    cout<<1;
                }else{
                    cout<<0;    
                }
            }
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

posted @ 2021-05-10 09:24  Endeavo_r  阅读(161)  评论(0)    收藏  举报