第十三届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组

第十三届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组小结

提示:代码为比赛时本人提交的代码,不代表是正解!!!

试题 A: 九进制转十进制

暴力

1478

试题 B: 顺子日期

012居然不算QAQ!!!!!!!

反正也是暴力,根据队友的答案应该是

4

试题 C: 刷题统计

假设需要用x周+y天,我们可以快速求出需要用多少周,再慢慢减求出多出几天就行

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 1e5+9;
int main(){
    ll a,b,n;
    scanf("%lld %lld %lld",&a,&b,&n);
    ll num = n/(5*a+2*b);
    n = n - num*(5*a+2*b);
    num = num*7;
    for(int i = 1;i <= 7;i++){
        if(n <= 0) break;
        if(i <= 5){
            n -= a;
            num++;
        }else{
            n -= b;
            num++;
        }
    }
    printf("%lld",num);
    return 0;
}

试题 D: 修剪灌木

第i个灌木如何长最高呢,那就是爱丽丝从当前灌木往左剪回来i,和往右剪回来i,看看哪个高。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 1e5+9;
int n;
int a[N];
int maxx[N];
int main(){
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        maxx[i] = max(2*(i-1),2*(n-i));
    }
    for(int i = 1;i <= n;i++){
        printf("%d\n",maxx[i]);
    }
    return 0;
}

试题 E: X 进制减法

因为a是大于b的,所以想要让a-b尽可能小,就要让每一位的进制尽可能小。

pa[i]代表的是第i+1位数1转化为十进制的大小

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 1e6+9;
const ll mod = 1e9+7;
ll pow_mod(ll a,ll b){
    ll ans = 1;
    ll base = a;
    while(b){
        if(b&1) ans = (ans * base) % mod;
        base = (base * base) % mod;
        b >>= 1;
    }
    return ans;
}
ll n;
ll a[N];
ll b[N];
ll na,nb;
ll pa[N];
int main(){
    scanf("%lld",&n);
    scanf("%lld",&na);
    for(ll i = 1;i <= na;i++){
        scanf("%lld",&a[i]);
    }
    reverse(a+1,a+1+na);
    scanf("%lld",&nb);
    for(ll i = 1;i <= nb;i++){
        scanf("%lld",&b[i]);
    }
    reverse(b+1,b+1+nb);
    ll p = max(na,nb);
    ll ans = 0;
    pa[0] = 1;
    for(ll i = 1;i <= p;i++){
        ll maxx = max(a[i],b[i]);
        ll x = max(2ll,maxx + 1);
        pa[i] = (pa[i-1]*x)%mod;
        ans = (ans + a[i]*pa[i-1] - b[i]*pa[i-1] + mod) % mod;
    }
    printf("%lld",ans);
    return 0;
}

试题 F: 统计子矩阵

比赛时算错复杂度,用二维前缀和暴力算的。70分

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 5e2+9;
ll a[N][N];
ll pre[N][N];
ll work(int x1,int y1,int x2,int y2){
    return pre[x2][y2] - pre[x1-1][y2] - pre[x2][y1-1] + pre[x1-1][y1-1]; 
}
int main(){
    ll ans = 0;
    ll n,m,k;
    scanf("%lld %lld %lld",&n,&m,&k);
    for(ll i = 1;i <= n;i++){
        for(ll j = 1;j <= m;j++){
            scanf("%lld",&a[i][j]);
            pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + a[i][j];
        }
    }
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= m;j++){
            for(int p = i;p <= n;p++){
                for(int l = j;l <= m;l++){
                    ll x = work(i,j,p,l);
                    if(x <= k) ans++;
                }
            }
        }
    }
    printf("%lld",ans);
    return 0;
}

试题 G: 积木画

不会!!!!!!!

试题 H: 扫雷

根据雷和雷的关系建一张有向图,注意因为r最大是10,所以最多只用在平面上找20*20个点,用map存图,比赛时没算复杂度感觉能过,现在算了一下,50000 * 20 * 20 * log(50000)有点极限,希望测评机够快。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 1e6+9;
struct node{
    ll x,y,r;
}e[N];
vector<int> g[N];
map<pair<ll,ll> ,int> mp;
ll dis(ll x1,ll y1,ll x2,ll y2){
    return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
}
int vis[N];
void dfs(int now){
    if(vis[now]) return ;
    vis[now] = 1;
    for(int i = 0;i < g[now].size();i++){
        int to = g[now][i];
        if(!vis[to]) dfs(to);
    }
}
int main(){
    ll n,m,r;
    scanf("%lld %lld %lld",&n,&m,&r);
    for(ll i = 1;i <= n;i++){
        scanf("%lld %lld %lld",&e[i].x,&e[i].y,&e[i].r);
        mp[make_pair(e[i].x,e[i].y)] = i;
    }
    for(int k = 1;k <= n;k++){
        for(int i = -e[k].r;i <= e[k].r;i++){
            for(int j = -e[k].r;j <= e[k].r;j++){
                ll xx = e[k].x+i,yy = e[k].y+j;
                if(dis(e[k].x,e[k].y,xx,yy) <= e[k].r*e[k].r){
                    if(mp[make_pair(xx,yy)]){
                        g[k].push_back(mp[make_pair(xx,yy)]);
                    }
                }
            }
        }
    }
    for(ll k = 1;k <= m;k++){
        for(int i = -e[k].r;i <= e[k].r;i++){
            for(int j = -e[k].r;j <= e[k].r;j++){
                ll xx = e[k].x+i,yy = e[k].y+j;
                if(dis(e[k].x,e[k].y,xx,yy) <= e[k].r*e[k].r){
                    if(mp[make_pair(xx,yy)]){
                        int now = mp[make_pair(xx,yy)];
                        if(!vis[now])
                            dfs(now);
                    }
                }
            }
        }
    }
    ll ans = 0;
    for(int i = 1;i <= n;i++){
        if(vis[i]) ans++;
    }
    printf("%lld",ans);
    return 0;
}

试题 I: 李白打酒加强版

三维dp,定义d[i] [j] [k]表示前i个去处,去了j家店,还剩余k斗酒有多少种情况。

因为最后一定要遇到花,所以d[n+m] [n] [0]一定只能由d[n+m-1] [n] [1]转移而来,所以输出d[n+m-1] [n] [1]即可

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const ll N = 2e2+9;
const ll mod = 1000000007;
ll d[N][N][N];
ll n,m;
int main(){
    d[0][0][2] = 1;
    scanf("%lld %lld",&n,&m);
    ll ans = 0;
    for(int i = 1;i <= n+m;i++){
        for(int j = 0;j <= n;j++){
            for(int k = 0;k <= m;k++){
                if(i != n+m){
                    if(d[i-1][j][k]){
                        if(k > 0){
                            d[i][j][k-1] = (d[i][j][k-1] + d[i-1][j][k])%mod;
                        }
                        if(k*2 <= m){
                            d[i][j+1][k*2] = (d[i][j+1][k*2] + d[i-1][j][k])%mod;
                        }
                    }    
                }
                
            }
        }
    }
    printf("%lld",d[n+m-1][n][1]);
    return 0;
}

试题 J: 砍竹子

写完i没时间看了QAQ

你可能感兴趣的:(蓝桥杯)