蓝桥题解

最大子序列和

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
//题目 1508: [蓝桥杯][算法提高VIP]和最大子序列
ll a[110000],n;
//求跨中点的最大子序列和
ll cross_dfs(ll l,ll r,ll mid){
    ll sum_left=0,sum_right=0;
    ll pre_left=0,pre_right=0;
    //求左半区最大的后缀和
    for(ll i=mid;i>=l;i--){
        pre_left+=a[i];
        if(sum_left<pre_left)sum_left=pre_left;
    }
    //求右半区最大的前缀和
    for(ll i=mid+1;i<=r;i++){
        pre_right+=a[i];
        if(sum_right<pre_right)sum_right=pre_right;
    }
    return sum_left+sum_right;
}
//求区间[l,r]的最大子序列和
ll dfs(ll l,ll r){
    if(l==r){
        return a[l];
    }
    ll mid=(l+r)>>1;
    ll sum_left=dfs(l,mid);//左半区的最大子序列和
    ll sum_right=dfs(mid+1,r);//右半区的最大子序列和
    ll sum_cross=cross_dfs(l,r,mid);//跨中点的最大子序列和
    if(sum_left>=sum_right&&sum_left>=sum_cross)return sum_left;
    if(sum_right>=sum_left&&sum_right>=sum_cross)return sum_right;
    return sum_cross;
}

int main()
{
    IOS;
    cin>>n;
    for(ll i=1;i<=n;i++){
        cin>>a[i];
    }
    cout<<dfs(1,n)<<endl;
    getchar();
    getchar();
    return 0;
}
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f;
ll a[110000],n;
ll dp[110000];//dp[i]表示以下标i结尾的元素的最大子段和

int main()
{
    IOS;
    cin>>n;
    for(ll i=1;i<=n;i++){
        cin>>a[i];
    }
    ll ans=-INF;//初始化为负无穷
    for(ll i=1;i<=n;i++){
        if(dp[i-1]<=0){//对dp[i]没有增加的作用
            dp[i]=a[i];
        }
        else dp[i]=dp[i-1]+a[i];
        ans=max(dp[i],ans);
    }
    cout<<ans<<endl;
    getchar();
    getchar();
    return 0;
}

 

 DNA

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
//题目 1115: DNA
void print(ll a)
{
    //上半部分
    for (ll i = 2; i <= a / 2; i++)
    {
        for (ll j = 1; j <= a - i + 1; j++)
        {
            if (j == i || j == a - i + 1)
                cout << "X";
            else
                cout << " ";
        }
        cout << endl;
    }
    //下半部分
    for (ll i = a / 2 + 1; i <= a; i++)
    {
        for (ll j = 1; j <= i; j++)
        {
            if (j == a - i + 1 || j == i)
                cout << "X";
            else
                cout << " ";
        }
        cout << endl;
    }
}

int main()
{
    IOS;
    ll n, a, b;
    while (cin >> n)
    {
        while (n--)
        {
            cin >> a >> b;
            for(ll i=1;i<=a;i++){
                if(i==1||i==a)cout<<"X";
                else cout<<" ";
            }
            cout<<endl;
            while (b--)
            {
                print(a);
            }
            if (n > 0)
                cout << endl;
        }
    }
    getchar();
    getchar();
    return 0;
}

 公交车

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f;
ll fee[15];//费用
ll dp[550];//dp[i]走i公里需要花费的最少费用
//题目 1282: 公交汽车
int main()
{
    IOS;
    ll n;
    for(ll i=1;i<=10;i++){
        cin>>fee[i];
    }
    cin>>n;
    dp[0]=0;//走0公里需要花费为0
    for(ll i=1;i<=n;i++){
        dp[i]=INF;
        //对前k步进行遍历
        for(ll k=1;k<=10;k++){
            ll pre=i-k;
            if(pre<0)break;
            dp[i]=min(dp[pre]+fee[k],dp[i]);//动态规划方程
        }
    }
    cout<<dp[n]<<endl;
    getchar();
    getchar();
    return 0;
}

 抢夺资源

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
//题目 2108: 抢夺资源
int main()
{
    IOS;
    ll n,m;
    while(cin>>n>>m){
        if(n%(m+1)==0){
            cout<<"Wildhunte"<<endl;
        }
        else cout<<"Gerlot"<<endl;
    }
    getchar();
    getchar();
    return 0;
}

递推求值

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
//题目 1907: [蓝桥杯][算法提高VIP]递推求值
const ll mod=99999999;
struct matrix{
    ll m[10][10];
};
ll f[8]={6,5,1,4,2,3,5,3};
matrix e;//底数矩阵
void init_e(){
    for(ll i=0;i<8;i++){
        for(ll j=0;j<8;j++){
            e.m[i][j]=0;
        }
    }
    e.m[0][1]=e.m[0][6]=1;
    e.m[1][4]=3;e.m[1][5]=e.m[0][4]=2;
    e.m[1][0]=e.m[1][7]=e.m[2][0]=1;
    e.m[3][1]=e.m[4][2]=e.m[5][3]=e.m[6][6]=e.m[7][7]=1;
}
//矩阵a乘以矩阵b
matrix multi(matrix a,matrix b){
    matrix temp;
    memset(temp.m,0,sizeof(temp.m));
    for(ll i=0;i<8;i++){
        for(ll j=0;j<8;j++){
            for(ll k=0;k<8;k++){
                temp.m[i][j]=(temp.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
            }
        }
    }
    return temp;
}
//矩阵快速幂
matrix quick(matrix a,ll b){
    matrix sum;
    //单位矩阵
    for(ll i=0;i<8;i++)
        for(ll j=0;j<8;j++)
            if(i==j)sum.m[i][j]=1;
            else sum.m[i][j]=0;
    while(b){
        if(b&1){
            sum=multi(sum,a);
        }
        b>>=1;
        a=multi(a,a);
    }
    return sum;
}

int main()
{
    IOS;
    init_e();
    ll n;
    cin>>n;
    if(n<4){
        if(n==1)cout<<2<<endl<<3<<endl;
        else if(n==2)cout<<1<<endl<<4<<endl;
        else cout<<6<<endl<<5<<endl;
        return 0;
    }
    matrix M=quick(e,n-3);
    ll ans[2]={0,0};
    for(ll k=0;k<2;k++){
        for(ll i=0;i<8;i++){
            ans[k]=(ans[k]+M.m[k][i]*f[i])%mod;
        }
    }
    cout<<ans[0]<<endl<<ans[1]<<endl;
    getchar();
    getchar();
    return 0;
}

 

广场舞 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;

//1838	[蓝桥杯][2015年第六届真题]广场舞


//点
struct Point
{
    int x, y;
};
//线
struct Line
{
    Point p1, p2;
};
//存取列分割线与多边形交点的纵坐标
struct node_y
{
    double yl, yr;
};

Point point[maxn];
Line line[maxn];
node_y pre[maxn];
int n;
//求分割线与指定的边的交点纵坐标
double gety(double x, Line l)
{
    double y, x1, y1, x2, y2;
    x1 = l.p1.x, y1 = l.p1.y, x2 = l.p2.x, y2 = l.p2.y;
    y = (y2 - y1) * (x - x1) / (x2 - x1) + y1;
    return y;
}
//对交点排序
bool cmp(node_y n1, node_y n2)
{
    return n1.yl < n2.yl;
}

int solve()
{
    int res, cnt, minn, maxx, l, r, i, j;
    minn = 1000, maxx = -1000;
    //求出x值的最小值和最大值
    for (i = 0; i < n; i++)
    {
        minn = min(minn, point[i].x), maxx = max(maxx, point[i].x);
    }
    res = 0;
    //从左到右依次遍历分割线,每次循环有两条分割线确定一列
    for (i = minn + 1; i <= maxx; i++)
    {
        cnt = 0;
        for (j = 0; j < n; j++)//遍历多边形每一条边
        {
            l = line[j].p1.x, r = line[j].p2.x;
            if (i-1>=l && i <= r)
            {
                //存下每条边交点的纵坐标对
                pre[cnt].yl = gety(i - 1, line[j]);
                pre[cnt].yr = gety(i, line[j]);
                cnt++;
            }
        }
        sort(pre, pre + cnt, cmp);//排序
        for (j = 0; j < cnt / 2; j++)
        {
            //两两一组
            l = int(ceil(max(pre[2 * j].yl, pre[2 * j].yr)));//最大者向上取整
            r = int(floor(min(pre[2 * j + 1].yl, pre[2 * j + 1].yr)));//最小者向下取整
            if (l < r)
                res += (r - l);
        }
    }
    return res;
}

int main()
{
    int i, ans;
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d%d", &point[i].x, &point[i].y);
    }
    for (i = 0; i < n; i++)
    {
        line[i].p1 = point[i], line[i].p2 = point[(i + 1) % n];
        if (line[i].p1.x > line[i].p2.x)
        {
            swap(line[i].p1, line[i].p2);//统一是第一个端点为左侧端点
        }
    }
    printf("%d\n", solve());
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值