【题目记录】——浙江工业大学19届杭银理财杯

文章目录

  • A Grammy Wants to Earn Big Money 简单题
  • C Terrible Additive Number Theory Problem 打表找规律
  • D Interstellar 思维
  • E Recharge Cycle
  • G Resource Calculator 模拟
  • H Minimum Edit Distance 简单思维
  • J Mountain 贪心
  • K Pairing Game 线段树
  • M A Chinese Idiom 简单思维

A了7个题,还好吧,好像有两个题是猜出来的?只能说我的队友太强了。
这边也要整理一下后面搞明白的题目
目前还没有重现的题目链接,不知道后面会不会有,有的话补充上
先上一个pdf链接
「The_19th_ZJUTCPC.pdf」

部分题意和思路,我请教队友后补上。先上代码

A Grammy Wants to Earn Big Money 简单题

题目大意:小g一周工作五天周一到周五,然后今天是周日,算上今天未来n天之内,小g要工作几天。
思路:先算出来n天里面有几个整周,每周工作五天,计算剩下的天数还能工作几天,最多工作五天。然后加到一起就行了

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

void solve()
{
	int n;
	cin >> n;
	cout << (n-1)/7*5+((n-1)%7>5?5:(n-1)%7)<<endl;
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
//	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

C Terrible Additive Number Theory Problem 打表找规律

题目大意: P i P_i Pi是第i个质数。 x = ∏ i = l r P i x=\prod_{i=l}^{r}P_i x=i=lrPi,问有多少个x( x ≤ n x\le n xn)满足 x = 2 k P r + 1 − 1 x=2^kP_{r+1}-1 x=2kPr+11
思路:队友打表发现满足条件的数只有一组,然后就是小于这个数就输出0,大于这个数就输出1就行了。。。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n;
    cin >>n;
    if(n>=2431)
        cout<<1<<endl;
    else
        cout <<0<<endl;
    return 0;
}

D Interstellar 思维

题目大意:每一个点都有一个权值 a j a_j aj,从i点到j点消耗的能量是 ( j − i ) 3 ∗ a j (j-i)^3*a_j (ji)3aj(i<j)问从1-n点最少要消耗多少能量。
思路:用一个val[j]数组记录到达j点需要的最少的花费
如果完全暴力的方法就是对于每一个j都暴力计算从每一个i点到达j点的花费然后取最小值,复杂度是 n 2 n^2 n2,显然会超时
考虑优化,我们看这个消耗能量的公式, ( j − i ) 3 a j (j-i)^3a_j (ji)3aj,那么对于j点来说,我们没有必要让i从1开始,而是找到一个最大的距离即可,比这个距离更大的点不可能发展为最优解,相当于一个剪枝,我当时算出来的这个距离是100,结果wa了,后面我们根据时间复杂度取了个最大的可用距离值就过了,具体原理我还没太搞清楚。由此可见,我们优化的时候,尽量取到时间复杂度的最大值。
然后还有一个小优化是,对于一个j来说,我们试图从i或k到j取最优值,(i<k),如果val[i]>val[k]那么这个i点就不需要再计算一次了,因为他不可能发展为最优解。
AC代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e5+6,len=900;//这个len就是那个最大的距离,我们一开始取100 wa了,然后取了个900就过了
ll a[N];
ll val[N];

int cal(int x)
{
    return x*x*x;
}
void solve()
{
	int n;
	cin >> n;
    for(int i = 1;i <= n;i++)
    {
        scanf("%lld",a+i);
    }
    memset(val,0xf,sizeof(val));
    val[1]=0;
    if(n<=len)
    {
        for(int j = 2;j <= n;j++)
        {
            for(int i = 1;i <=j-1;i++)
            {
                val[j]=min(val[j],cal(j-i)*a[j]+val[i]);
            }
        }
    }
    else{
        for(int j = 2;j <= len;j++)
        {
            for(int i = 1;i <=j-1;i++)
            {
                val[j]=min(val[j],cal(j-i)*a[j]+val[i]);
            }
        }
        for(int j = len+1;j <= n;j++)
        {
            ll t = 1e18;
            for(int i = j-1;i>=j-len;i--)
            {
                if(val[j]<t)
                {
                    val[j]=min(val[j],cal(j-i)*a[j]+val[i]);
                }
            }
        }
    }
    printf("%lld\n",val[n]);
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
//	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

E Recharge Cycle

题目大意:给出4个数,四个能量的最大容量值,每一个容器能量满了之后,会消耗掉自身所有的能量,然后给所有四个数增加c[i][j]的能量,i表示第i个容器给第j个容器增加的能量值,问对于给出的数据能否一直循环下去
思路:就是求后四行每一列的和是否全部大于等于对应容器的容量,是则输出yes,否则输出NO。

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int c[4],a[4][4],s[4];
void solve()
{
    for(int i = 0;i < 4;i++)
    {
        cin >> c[i];
    }
    for(int i = 0;i < 4;i++)
    {
        for(int j = 0;j < 4;j++)
        {
            cin >> a[i][j];
        }
    }
    for(int i = 0;i < 4;i++)
    {
        for(int j = 0;j < 4;j++)
        {
            s[i]+=a[j][i];
        }
    }
    bool flag=false;
    for(int i = 0;i < 4;i++)
    {
        if(s[i]<c[i])
        {
            flag=true;
            break;
        }
    }
    if(flag==false)
    {
        cout << "Yes" << endl;
    }
    else
    {
        cout << "No" << endl;
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    int t = 1;
//	scanf("%d",&t);
    while(t--)
    {
        solve();
    }
    return 0;
}

G Resource Calculator 模拟

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <stack>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <queue>

#define fill(a, b, c, d) a[b][c] = d;

auto read = std::bind(std::scanf, "%d", std::placeholders::_1);
auto readu = std::bind(std::scanf, "%u", std::placeholders::_1);

using ll = long long;

const int MAXN = 1e4 + 5, inf = 0x3f3f3f3f;
const double PI = acos(-1);

int gem[MAXN][4], amd[MAXN][3];
int tmd[MAXN][3], tb[MAXN][3];

int mexp[]{
		0,1000,1325,1700,2150,2625,3150,3725,4350,5000,5700,
		6450,7225,8050,8925,9825,10750,11725,12725,13775,
		14875,16800,18000,19250,20550,21875,23250,24650,
		26100,27575,29100,30650,32250,33875,35550,37250,
		38975,40750,42575,44425,46300,50625,52700,54775,
		56900,59075,61275,63525,65800,68125,70475,76500,
		79050,81650,84275,86950,89650,92400,95175,98000,
		100875,108950,112050,115175,118325,121525,124775,
		128075,131400,134775,138175,148700,152375,156075,
		159825,163600,167425,171300,175225,179175,183175,
		216225,243025,273100,306800,344600,386950,434425,487625,547200
	};
int bd[] {
	0, 2, 4, 8, 12, 20
};
int spec[] {
	3, 10, 20, 30, 45, 60
};
int acoin[] {
	20000, 40000, 60000, 80000, 100000, 120000
};
int tcoin[] {
	0, 12500, 17500, 25000, 30000, 37500, 120000, 260000, 450000, 700000
};
int wbd[] {
	0, 0, 0, 0, 0, 0, 1, 1, 2, 2
};
int coi[] {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};
void init()
{
	gem[0][0] = 1; gem[1][1] = 3; gem[2][1] = 6;
	gem[3][2] = 3; gem[4][2] = 6; gem[5][3] = 6;

	amd[0][0] = 3; amd[1][0] = 15; amd[2][1] = 12;
	amd[3][1] = 18; amd[4][2] = 12; amd[5][2] = 24;

	fill(tmd, 1, 0, 6); fill(tmd, 2, 1, 3); fill(tmd, 3, 1, 4); fill(tmd, 4, 1, 6); fill(tmd, 5, 1, 9);
	fill(tmd, 6, 2, 4); fill(tmd, 7, 2, 6); fill(tmd, 8, 2, 9); fill(tmd, 9, 2, 12);

	fill(tb, 1, 0, 3); fill(tb, 2, 1, 2); fill(tb, 3, 1, 4); fill(tb, 4, 1, 6); fill(tb, 5, 1, 9);
	fill(tb, 6, 2, 4); fill(tb, 7, 2, 6); fill(tb, 8, 2, 12); fill(tb, 9, 2, 16);
}

namespace res {
	int coin, spec, bd, wbd, coi;
	int exp[3], gem[4], md[3], tb[3];
	void clear() {
		coin = spec = bd = wbd = coi = 0;
		memset(exp, 0, sizeof(exp));
		memset(gem, 0, sizeof(gem));
		memset(md, 0, sizeof(md));
		memset(tb, 0, sizeof(tb));
	}

	void print() {
		printf("%d %d %d %d %d\n", coin, spec, bd, wbd, coi);
		printf("%d %d %d\n", exp[0], exp[1], exp[2]);
		printf("%d %d %d %d\n", gem[0], gem[1], gem[2], gem[3]);
		printf("%d %d %d\n", md[0], md[1], md[2]);
		printf("%d %d %d\n", tb[0], tb[1], tb[2]);
	}
}

bool judge(int i) {
	return i == 20 || i == 40 || i == 50 || i == 60 || i == 70 || i == 80;
}

int main()
{
	freopen("test.in", "r", stdin);
	init();
	int T;
	read(&T);
	while (T--)
	{
		res::clear();
		int a0, l0, t0[3], a, l, t[3];
		scanf("%d%d%d%d%d%d%d%d%d%d", &l0, &a0, t0, t0 + 1, t0 + 2, &l, &a, t, t + 1, t + 2);

		int totExp = 0, trueExp = 0;

		while(a0 < a) {
			bool flag = true;
			for(; a0 < a && (!judge(a0) || flag); ++a0) {
				totExp += mexp[a0];
				flag = false;
			}
			res::coin += totExp / 5;
			totExp = 1ll * (totExp + 999) / 1000 * 1000;
			while(totExp >= 2e4) totExp -= 2e4, res::exp[2]++, trueExp += 2e4;
			while(totExp >= 5e3) totExp -= 5e3, res::exp[1]++, trueExp += 5e3;
			while(totExp > 0) totExp -= 1e3, res::exp[0]++, trueExp += 1e3;
		}

		for(int i = l0; i < l; ++i) {
			for(int j = 0; j < 4; ++j) res::gem[j] += gem[i][j];
			res::bd += bd[i];
			for(int j = 0; j < 3; ++j) res::md[j] += amd[i][j];
			res::spec += spec[i];
			res::coin += acoin[i];
		}

		for(int tt = 0; tt < 3; ++tt) {
			for(int i = t0[tt]; i < t[tt]; ++i) {
				res::coin += tcoin[i];
				for(int j = 0; j < 3; ++j) res::md[j] += tmd[i][j];
				for(int j = 0; j < 3; ++j) res::tb[j] += tb[i][j];
				res::wbd += wbd[i];
				res::coi += coi[i];
			}
		}
		res::print();
	}
	return 0;
}

H Minimum Edit Distance 简单思维

题目大意:蛮容易理解的
思路:队长说就是读入两个字符串随便输出一个就行。。

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

void solve()
{
    string str1,str2;
	cin >> str1 >> str2;
	cout << str1 << endl;
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
//	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

J Mountain 贪心

题目大意:花费一个体力可以爬a米,花费b个体力可以跳c米,体力小于b时,用光所有的体力可以跳c米,一开始有S体力,问最远爬多少米。
思路:先比较单位体力是跳得高还是爬得高,然后剩余体力在做比较,就是一个简单的贪心问题。

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

void solve()
{
	ll a,b,c,s;
	scanf("%lld%lld%lld%lld",&a,&b,&c,&s);
	ll num=0;
	ll res=0,yu=0;
	if(c>a*b)
    {
        num=s/b;
        yu=s%b;
        if(yu==0)
        {
            yu=b;
            num--;
        }
        res+=(num*c);
        res+=((yu-1)*a+c);
    }
    else
    {
        if(c>=a)
        {
            res+=((s-1)*a+c);
        }
        else
        {
            res+=(s*a);
        }
    }
    printf("%lld\n",res);
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

K Pairing Game 线段树

#include<bitsdc++.h>
using namespace std;
const int N=6e5+10;
int bz[N*4],cc[N*4];
long long tr[N*4];
int b[N],le[N],ri[N],a[N];
void build(int rt,int l,int r)
{
	bz[rt]=0;
	if (l==r) 
	{
		tr[rt]=b[l];
		cc[rt]=1;
		return;	
	}
	int mid=l+r>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	tr[rt]=tr[rt<<1]+tr[rt<<1|1];
	cc[rt]=cc[rt<<1]+cc[rt<<1|1];
}
void push(int rt,int l,int r)
{
	int ll=rt<<1,rr=rt<<1|1;
	bz[ll]+=bz[rt];
	bz[rr]+=bz[rt];
	tr[ll]+=1ll*bz[rt]*cc[ll];
	tr[rr]+=1ll*bz[rt]*cc[rr];
	bz[rt]=0;	
}
void modify(int rt,int l,int r,int x,int y)
{
	if (l>=x&&r<=y) 
	{
		tr[rt]-=cc[rt];
		bz[rt]--;
		return;	
	}
	if (bz[rt]) push(rt,l,r);
	int mid=l+r>>1;
	if (x<=mid) modify(rt<<1,l,mid,x,y);
	if (y>mid) modify(rt<<1|1,mid+1,r,x,y);
	tr[rt]=tr[rt<<1]+tr[rt<<1|1];
	cc[rt]=cc[rt<<1]+cc[rt<<1|1];
}
void mo(int rt,int l,int r,int x)
{
	if (l==r)
	{
		tr[rt]=0;
		cc[rt]=0;
		return;	
	}
	if (bz[rt]) push(rt,l,r);
	int mid=l+r>>1;
	if (x<=mid) mo(rt<<1,l,mid,x);
	else mo(rt<<1|1,mid+1,r,x);
	tr[rt]=tr[rt<<1]+tr[rt<<1|1];
	cc[rt]=cc[rt<<1]+cc[rt<<1|1];
}
int main()
{
	int n;
	scanf("%d",&n);
	for (int i=1;i<=2*n;i++) 
	{
		scanf("%d",&a[i]);
		if (!le[a[i]]) le[a[i]]=i;
		else ri[a[i]]=i;
	}
	int tmp=0;
	for (int i=1;i<=2*n;i++)
	{
		b[i]=tmp;
		if (le[a[i]]==i) tmp++;else tmp--,b[i]--;
	}
	build(1,1,2*n);
	for (int i=n;i>=1;i--)
	{
		modify(1,1,2*n,le[i],ri[i]);
		mo(1,1,2*n,le[i]);
		mo(1,1,2*n,ri[i]);
		printf("%lld\n",tr[1]);
	}
}

M A Chinese Idiom 简单思维

签到题
不多说了代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

double lifang(double d)
{
    return d*d*d;
}

void solve()
{
	double r1,r2,d1;
	scanf("%lf%lf%lf",&r1,&r2,&d1);
	double d2=lifang(r2)-lifang(r1)+lifang(r1-d1);
	double res=pow(d2,1.0/3);
//	cout<<pow(27,1.0/3)<<endl;
	res=r2-res;
	printf("%.10lf\n",res);
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值