文章目录
- 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
x≤n)满足
x
=
2
k
P
r
+
1
−
1
x=2^kP_{r+1}-1
x=2kPr+1−1
思路:队友打表发现满足条件的数只有一组,然后就是小于这个数就输出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
(j−i)3∗aj(i<j)问从1-n点最少要消耗多少能量。
思路:用一个val[j]数组记录到达j点需要的最少的花费
如果完全暴力的方法就是对于每一个j都暴力计算从每一个i点到达j点的花费然后取最小值,复杂度是
n
2
n^2
n2,显然会超时
考虑优化,我们看这个消耗能量的公式,
(
j
−
i
)
3
a
j
(j-i)^3a_j
(j−i)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;
}