郑州轻工业大学“CCPC2019-河南省赛”选拔赛(2) 部分题解

题目链接

A 火柴棒等式 <暴力>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
 
int x[] =
{
0
,0
,0
,0
,0
,0
,0
,0
,0
,0
,0
,0
,0
,1
,2
,8
,9
,6
,9
,29
,39
,38
,65
,88
,128
,194
,323
,472
,656
};
 
int main()
{
#ifdef LOCAL
    //freopen("C:/input.txt", "r", stdin);
#endif
    int y;
    while (scanf("%d", &y) != EOF)
        printf("%d\n", x[y]);
 
    return 0;
}

C set <数论>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
 
int gcd(int a, int b)
{
    if (!b)
        return a;
    return gcd(b, a % b);
}
int main()
{
#ifdef LOCAL
    //freopen("C:/input.txt", "r", stdin);
#endif
    int n, p;
    cin >> n >> p;
    int g = p;
    for (int i = 1; i <= n; ++i)
    {
        int x;
        scanf("%d", &x);
        g = gcd(g, x);
    }
    cout << p / g <<endl;
 
    return 0;
}

E 小L的加法器 <贪心>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
 
int main()
{
#ifdef LOCAL
    //freopen("C:/input.txt", "r", stdin);
#endif
    int n;
    cin >> n;
    priority_queue<ll, vector<ll>, greater<ll>> pq;
    for (int i = 0; i < n; ++i)
    {
        ll x;
        scanf("%lld", &x);
        pq.push(x);
    }
    ll ans = 0;
    while (--n)
    {
        ll a = pq.top();
        pq.pop();
        ll b = pq.top();
        pq.pop();
        ans += a + b;
        pq.push(a + b);
    }
    cout <<ans << endl;
 
    return 0;
}

F 天天的钢琴 <组合数>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
ll fac[N], inv[N];
ll a[N];
 
ll mpow(ll a, ll b, ll c)
{
    ll t = 1;
    while (b)
    {
        if (b & 1)
            t = t * a % c;
        a = a * a % c;
        b >>= 1;
    }
    return t;
}
ll C(int n, int m)
{
    return fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
int main()
{
#ifdef LOCAL
    freopen("C:/input.txt", "r", stdin);
#endif
    fac[0] = inv[0] = 1;
    for (int i = 1; i < N; ++i)
    {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = mpow(fac[i], MOD - 2, MOD);
    }
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; ++i)
        scanf("%lld", &a[i]);
    sort(a + 1, a + n + 1, greater<int>());
    ll ans = 0;
    for (int i = 1; i <= n - k + 1; ++i)
        ans = (ans + a[i] * C(n - i, k - 1) % MOD) % MOD;
    cout << ans <<endl;
 
    return 0;
}

G 小L的比赛密码

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
 
int main()
{
#ifdef LOCAL
    //freopen("C:/input.txt", "r", stdin);
#endif
    int x, y, z = 1, p;
    cin >> x >> y;
    while (cin >> p)
    {
        if (p > x || p < y)
            cout << z << endl, exit(0);
        z++;
    }
 
    return 0;
}

H 别踩黑块! <单调栈>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e3 + 10;
char g[N][N];
int H[N]; //列连续数量

struct node
{
	int h, w; //高度宽度
};
int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int n, m;
	while (cin >> n >> m)
	{
		memset(H, 0, sizeof(H));
		for (int i = 1; i <= n; ++i)
			scanf("%s", g[i] + 1);
		ll ans = 0;
		for (int i = 1; i <= n; ++i) //枚举行
		{
			stack<node> stk; //维护连续且高度递增的矩阵
			ll cnt = 0; //高度不大于当前高度的矩阵数量
			for (int j = 1; j <= m; ++j) //计算以g[i][j]为右下角的矩阵数量
				if (g[i][j] == 'W')
				{
					H[j] = cnt = 0; //打断连续
					while (!stk.empty())
						stk.pop();
				}
				else
				{
					++H[j]; //列连续+1
					node t = { H[j], 1 }; //当前位置至少为一个H[j]*1的矩阵
					while (!stk.empty() && stk.top().h >= t.h) //原有高度和当前相等或受到当前高度限制
					{
						t.w += stk.top().w; //合并矩形宽度
						cnt -= 1LL * stk.top().w * stk.top().h; //减去超过的整块数量 下面会加上合并后的
						stk.pop();
					}
					stk.push(t);
					cnt += 1LL * t.h * t.w; //加上当前数量
					ans += cnt; //cnt原有数值表示再后面接上当前一列依然是合法矩阵
				}
		}
		cout << ans << endl;
	}

	return 0;
}

I 成员统计

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
 
int main()
{
#ifdef LOCAL
    freopen("C:/input.txt", "r", stdin);
#endif
    int n;
    cin >> n;
    map<int, int> mp;
    for (int i = 1; i <= n; ++i)
    {
        int x;
        scanf("%d", &x);
        ++mp[x];
    }
    for (auto it : mp)
        printf("%d %d\n", it.fst, it.sed);
 
    return 0;
}

J 小L的朋友 <树形dp>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 5e4 + 10;
vector<int> e[N];
int f[N][2];
 
void DFS(int x, int fz)
{
    f[x][1] = 1;
    for (int y : e[x]) if (y != fz)
    {
        DFS(y, x);
        f[x][0] += max(f[y][0], f[y][1]);
        f[x][1] += f[y][0];
    }
}
int main()
{
#ifdef LOCAL
    freopen("C:/input.txt", "r", stdin);
#endif
    int n;
    cin >> n;
    for (int i = 1; i < n; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    DFS(1, 0);
    cout << max(f[1][0], f[1][1]) << endl;
 
    return 0;
}

K 小L分切糕 <二分>

#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
 
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const long double pi = acos(-1);
int n, m;
vector<int> vec;
 
bool check(double ans)
{
    int cnt = 0;
    for (int i = 0; i < vec.size(); ++i)
    {
        double area = pi * vec[i] * vec[i];
        cnt += area / ans;
    }
    return cnt >= m;
}
int main()
{
#ifdef LOCAL
    //freopen("C:/input.txt", "r", stdin);
#endif
    cin >> n >> m;
    ++m;
    for (int i = 0; i < n; ++i)
    {
        int x;
        scanf("%d", &x);
        vec.push_back(x);
    }
    double l = 0, r = 1e18;
    while (abs(l - r) > 1e-6)
    {
        double m = (l + r) / 2;
        if (check(m))
            l = m;
        else
            r = m;
    }
    printf("%.3f\n", l);
 
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值