引言
这篇题解主要写写这几天排位赛做的题目,总结一下。因为会的题实在太少,所以我估计两篇博客就可以写完了……菜鸡哭泣qwq
DAY1
第一天只过了一道题,其中有一道方法思路都对了,但是因为一个很小的错误导致没有A掉,挺可惜的,毕竟好不容易碰到一道会的题目qwq
题意
有T组测试样例,每组给出一个整数n,求出长度为n的字符串的回文子串数目最少的字符串的数目。
“a”、“aa”、”aaa“都算一个回文字符串。
思路
这道题也是自闭了很久的题,一开始根据样例,以为直接模998244353就可以了,当成了一个快速幂的板子题。但其实不是qwq。后来认真思考后发现,当n大于3时,三个不相同的字母循环的序列是回文子串数目最少的字符串,例如abcabcabca这种,只有”a”、”b“、”c“三个回文子串,答案是(所以给出的那个让你模的数字就是个坑!!!);小于等于3的时候是。知道了做法,程序就很简单了。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<map> #include<vector> #include <utility> #define eps 1e-10 #define q first #define a second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int MAX=50010; const double pi = acos(-1.0); typedef long long ll;
int main() { int t,n; cin>>t; while(t--) { cin>>n; if(n<=3) cout<<pow(26,n)<<endl; else cout<<26*25*24<<endl; } return 0; }
|
题意
有n个机器人,每个机器人有一个初始位置和一个加速度,有公式v(t)=at
,各机器人初始速度为零。当一个机器人是唯一一个第一的时候,我们叫这个机器人为领头机器人,问整个过程中一共出现了多少个领头机器人。
- 有 T(1≤ T≤50)组测试数据
- 每组测试数据有N(0 < N≤ 50000)个机器人,每个机器人给出p(位置)和a(加速度)
思路
这道题我看完后第一个想到的就是n条一次直线投影到x轴上,从上往下看最多能看到几条直线。因为我做过,所以我第一个开的就是这个题,但是因为那个小错误死活调不出来,wa了十几发qwq……
这道题的关键是能想到把问题转化成一次直线,即以$t^2$为横坐标,以p为纵坐标,每个机器人的运动等效为一次直线,如图:
然后将每个点按位置从大到小排序,位置相同按加速度从大到小排序,然后维护一个单调栈就可以了。
遍历第二个点到第n个点,如果当前结点的加速度大于栈顶结点,则这个机器人一定能追上栈顶机器人,但要判断这个直线会不会栈顶直线盖住,即在栈顶机器人追上前一个机器人top-1(栈顶的第二个机器人)之前,先追上top-1机器人,如图:
这样的话,栈顶机器人就不会成为领头机器人,要pop出栈。这样每次选取栈顶前两条直线和新直线判断,直到在栈顶机器人之后追上前一个机器人,如图:
![3][3.png]
最后,由于题目中会给出位置和速度完全一样的机器人,而这两个机器人都不能成为领头机器人,所以要进行去重。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<map> #include<vector> #include <utility> #define eps 1e-10 #define q first #define a second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int MAX=50010; int c[MAX]; int top=0; typedef struct { double q; double a; }node; map<pii,int>mp; node b[MAX]; bool cmp(node a,node b) { if(a.q!=b.q) return b.q<a.q; else return b.a<a.a; } bool f1(node x,node y,node z) { return (x.q-z.q)*(y.a-x.a)-(x.q-y.q)*(z.a-x.a)<=0; } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); mp.clear(); for(int i=0;i<n;i++) { scanf("%lf%lf",&b[i].q,&b[i].a); pii t; t.q=b[i].q; t.a=b[i].a; mp[t]++;
} sort(b,b+n,cmp); top=0; for(int i=1;i<n;i++) { if(b[i].a>b[c[top]].a) { while(top>0&&f1(b[c[top-1]],b[c[top]],b[i])) { top--; } c[++top]=i; } } int ans=top+1; for(int i=0;i<=top;i++) { pii t; t.a=b[c[i]].a; t.q=b[c[i]].q; if(mp[t]>1) ans--; } printf("%d\n",ans); } return 0; }
|
DAY2
第二天的比赛极为凄惨的爆零了,三个人开了三个题,最后全都超时了qwq
题意
有一个游戏,需要玩家搭配装备。每一类装备有四种属性加成a,b,c,d,每类装备只能选择一种,给出装备的种类k,装备数量n,根据公式
求出最大的战斗力是多少
- 有T组数据,
- 每组数据有n个装备,k个装备种类,1≤n,k≤50
思路
这道题因为数据都很小,所以我想到的就是直接暴力,但是搜索树他卡了一个数据,就一直超时,特别难受。
这道题暴力不会超时,但是第i类装备数目为0的和数目为1的都不能加入搜索树,否则就会超时qwq
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include<iostream> #include<cstdio> #include<algorithm> #include<map> using namespace std; typedef long long ll; const int N=100; map<int,int>mp; struct node { ll a; ll b; ll c; ll d; }aa[N][N]; int num[N]; ll ans; int n,k; int ss[N]; int top; void find(ll a,ll b,ll c,ll d,int s) { if(s==top) { ll t=a*b*c*d; ans=max(t,ans); return; } for(int i=0;i<num[ss[s]];i++) { find((a+aa[ss[s]][i].a),(b+aa[ss[s]][i].b),(c+aa[ss[s]][i].c),(d+aa[ss[s]][i].d),s+1); } }
int main() { int t; cin>>t; while(t--) { cin>>n>>k; top=0; for(int i=0;i<=k;i++) num[i]=0; mp.clear(); ll at=100,bt=100,ct=100,dt=100; for(int i=0;i<n;i++) { int t,a1,b,c,d; cin>>t>>a1>>b>>c>>d; aa[t][num[t]].a=a1; aa[t][num[t]].b=b; aa[t][num[t]].c=c; aa[t][num[t]].d=d; num[t]++; mp[t]++; } for(int i=1;i<=k;i++) { if(mp[i]==1) { at+=aa[i][0].a; bt+=aa[i][0].b; ct+=aa[i][0].c; dt+=aa[i][0].d; } else if(mp[i]>1) { ss[top++]=i; } } ans=100*100*100*100; find(at,bt,ct,dt,0); printf("%lld\n",ans); } return 0; }
|