蓝桥杯2021

 

1550

#include <iostream>
using namespace std;

int main()
{
    cout << 3181;
    return 0;
}

1551

#include <iostream>
using namespace std;

int main()
{
    cout << 40257;
    return 0;
}

1552

#include <iostream>
using namespace std;

int main()
{
    cout << 2430;
    return 0;
}

1553

#include <iostream>
using namespace std;

int main()
{
    cout << 10266837;
    return 0;
}

1555

#include <iostream>
using namespace std;

int main()
{
    cout << 67108864;
    return 0;
}

1558

避免左右两盘称重时谁比谁重的问题,从-sum开始

闫式dp法

在这里插入图片描述

#include <iostream>
#define int long long int
using namespace std;

const int N = 1e5 + 10;

int n;

int a[110];
int vis[110];
int p[110];

int sum = 0;

int ssum = 0;

/*void dfs(int t)
{
	if (!p[t] && t != 0)
	{
		p[t] = 1;
		sum++;
		return;
	}
	for (int i = 1; i <= t; i++)
	{
		if (!vis[i])
		{
			vis[i] = 1;
			ssum = ssum + a[i];
			dfs(ssum);
			ssum = ssum - a[i];
			vis[i] = 0;
		}
	}
	return;
}
*/
int dp[110][300010];

signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		sum += a[i];
	}
	dp[0][N] = 1;
	for (int i = 1; i <= n; i++)
	{
		for (int j = -sum; j <= sum; j++)
		{
			dp[i][j + N] = dp[i - 1][j + N];
			if (j - a[i] >= -sum)
			{
				dp[i][j + N] = dp[i][j + N] || dp[i - 1][j - a[i] + N];
			}
			if (j + a[i] <= sum)
			{
				dp[i][j + N] = dp[i][j + N] || dp[i - 1][j + a[i] + N];
			}
		}
	}
	for (int j = 1; j <= sum; j++)
	{
		if (dp[n][j + N])
		{
			ssum++;
		}
	}
	cout << ssum;
	return 0;
}

1561

#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;

const int p = 1e9 + 7;

int f[5005][5005], n;

char s[5005];

int cal() {
    for (int i = 1; i <= n; i++) {
        if (s[i] == '(') {
            for (int j = 1; j <= n; j++)
                f[i][j] = f[i - 1][j - 1];
        }
        else {
            f[i][0] = (f[i - 1][0] + f[i - 1][1]) % p;
            for (int j = 1; j <= n; j++)
                f[i][j] = (f[i][j - 1] + f[i - 1][j + 1]) % p;
        }
    }
    for (int i = 0; i <= n; i++)if (f[n][i])return f[n][i];
}

signed main() {
    scanf("%s", s + 1);
    n = strlen(s + 1);
    f[0][0] = 1;
    int l = cal();
    reverse(s + 1, s + 1 + n);
    memset(f, 0, sizeof f);
    f[0][0] = 1;
    for (int i = 1; i <= n; i++)s[i] = '(' + ')' - s[i];
    int r = cal();
    cout << l * r % p;
}

1563

#include <iostream>
#define int long long int
using namespace std;

// 1 3 5 7 8 10 12
// 2
// 4 6 9 11

bool c(int t)
{
	if ((t % 4 == 0 && t % 100 != 0) || t % 400 == 0)
	{
		return true;
	}
	return false;
}

// 1972

// 31536000

// 46800999

signed main()
{
	int n;
	cin >> n;
	while (n--)
	{
	    //cout << 46800999 % 3600;
	    int t;
	    cin >> t;
	    t /= 1000;
	    int h, m, s;
	    //cout << (31 * 7 + 28 + 30 * 4) << " ";
	    //cout << 365 * 24 * 3600 << " ";
    	h = t / 3600;
	    //cout << t - h * 3600 << " ";
    	m = (t - h * 3600) / 60;
	    s = (t - h * 3600 - m * 60);
    	h %= 24;
    	printf("%02d:%02d:%02d\n", h, m, s);
	    //cout << 39 + 16 * 60 + 4240 * 3600;
	}
	return 0;
}

1564

通过观察,可以看出每一列的第一个有效数字都是一个组合数,为了找到N的位置,可以令第16列开始递减,然后比较每一列的第一个有效数,进行二分查找。

#include<iostream>
using namespace std;
int n;
typedef long long LL;
LL C(int a,int b)  
{
    LL res = 1;
    for(int i = a,j = 1;j <= b;i--,j++)
    {
        res = res * i / j;
        if(res > n) return res; 
    }
    return res;
}
bool check(int k)
{
    long long l =  2 * k, r = max((LL)n, l); 
    while(l < r)
    {
        LL mid = l + r>> 1;
        if(C(mid,k) >= n) r = mid;
        else l = mid + 1;
    }
    if(C(r,k) == n)
    {
        printf("%lld\n",r * (r + 1) / 2 + k + 1); 
        return true;
    }
    return false;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin>>n;
        for(int k = 16;;k--)
        {
            if(check(k)) break;
        }
    }
    return 0;
}

1565

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;

PII stk[100010];
int n,m;
int ans[100010];
 
int main()
{
    cin>>n>>m;
    int top=0;
    while (m -- )
    {
        int p,q;
        cin>>p>>q;
        if(p==0)
        {
            while(top && stk[top].x==0) q=max(q,stk[top--].y);
            while(top>=2 && stk[top-1].y<=q) top-=2;
            stk[++top]={0,q};
        }
        else if(top)
        {
            while(top && stk[top].x==1) q=min(q,stk[top--].y);
            while(top>=2 && stk[top-1].y>=q) top-=2;
            stk[++top]={1,q};
        }
    }
    int k=n,l=1,r=n;
    for(int i=1;i<=top;i++)
    {
        if(stk[i].x==0)
        {
            while(r>stk[i].y && l<=r) ans[r--]=k--;
        }
        else
        {
            while(l<stk[i].y && l<=r) ans[l++]=k--;
        }
        if(l>r) break; 
    }
    if(top%2)
    {
        while(l<=r) ans[l++]=k--;
    }
    else
    {
        while(l<=r) ans[r--]=k--;
    }
    for(int i=1;i<=n;i++) 
    {
        cout<<ans[i]<<" ";
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值