打星队的菜比来补题啦

用1~n所有数字用+,-,*,(,),组成计算式使得其得数为17。
思路:找规律可得,小于4绝对无法组成17,当n为4时,可使得(4+1)*3+2得出17,n为5时,可使得4*5-3*(2-1),对于n为偶数时,可以以4为基础,剩下的相邻两数两两组成(i+1-i)的形式得到1,从而对答案无影响;n为奇数时,则以5为基础,相同操作即可。
AC Code:
- #include <bits/stdc++.h>
-
- typedef long long ll;
- const int N=2e5+5;
- int n;
-
- int main(){
- std::ios::sync_with_stdio(false);
- std::cin.tie(0);
- std::cin>>n;
- if(n<4){
- std::cout<<-1<<'\n';
- return 0;
- }
- if(n%2==0){
- std::cout<<"(4+1)*3+2";
- for(int i=5;i<=n;i+=2){
- std::cout<<"*("<<i+1<<"-"<<i<<")";
- }
- std::cout<<'\n';
- }
- else{
- std::cout<<"4*5-3*(2-1)";
- for(int i=6;i<=n;i+=2){
- std::cout<<"*("<<i+1<<"-"<<i<<")";
- }
- std::cout<<'\n';
- }
- return 0;
- }
os:这种类型的题之前师哥给的题中有类似的,但是我没有及时想到,在做的时候也很长时间没想到4是最小的界限,使得WA了好多发,,就离谱

A有4种硬币2,3,17,19,B有4种硬币5,7,11,13,有若干组询问x,问谁能用更少的硬币凑出x。
思路:若同时有a和b两种面值的硬币,且a<b,则每a个b硬币可以用b个a硬币代替,故a硬币在最优解中小于b,所以对于比较小的范围我们可以暴力枚举得到答案,在一个较大的数情况下答案是一定的。
AC Code:
- #include <bits/stdc++.h>
-
- #define INF 0x3f3f3f3f
- typedef long long ll;
- const int N=1e5+5;
- int A[]={0,2,3,17,19};
- int B[]={0,5,7,11,13};
- int a[N],b[N];
- int x,q;
-
- int main(){
- std::ios::sync_with_stdio(false);
- std::cin.tie(0);
- memset(a,INF,sizeof(a));
- memset(b,INF,sizeof(b));
- a[0]=0,b[0]=0;
- for(int i=1;i<=4;i++){
- for(int j=A[i];j<=100000;j++){
- a[j]=std::min(a[j],a[j-A[i]]+1);
- }
- }
- for(int i=1;i<=4;i++){
- for(int j=B[i];j<=100000;j++){
- b[j]=std::min(b[j],b[j-B[i]]+1);
- }
- }
- std::cin>>q;
- while(q--){
- std::cin>>x;
- if(x>=100000){
- std::cout<<"A"<<'\n';
- continue;
- }
- if(a[x]>=INF&&b[x]>=INF){
- std::cout<<-1<<'\n';
- }
- else if(a[x]==b[x]){
- std::cout<<"both"<<'\n';
- }
- else if(a[x]>b[x]){
- std::cout<<"B"<<'\n';
- }
- else if(a[x]<b[x]){
- std::cout<<"A"<<'\n';
- }
- }
- return 0;
- }
os:这个题当时搞了好久到最后终于搞出来了,结果重测的时候被卡了,寄

给出k个人的初始坐标, 给出k个人在T秒内的动作,计算每一秒重叠的人的对数。
思路:直接模拟,每次走之后修改当前状态和下一个状态,注意人的对数是C(n,2)。
AC Code:
- #include <bits/stdc++.h>
-
- #define INF 0x3f3f3f3f
- typedef long long ll;
- const int N=3e3+5;
- const int M=2e3+5;
- int n,m,T,k;
- int ans[N],x[M],y[M],mp[M][M];
- char s[M][N];
-
- int main(){
- scanf("%d%d%d%d",&n,&m,&k,&T);
- for(int i=0;i<k;i++){
- scanf("%d%d",&x[i],&y[i]);
- ans[0]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- mp[x[i]][y[i]]++;
- ans[0]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- }
- for(int i=0;i<k;i++){
- scanf("%s",s[i]);
- }
- int cnt=1;
- for(int j=0;j<T;j++){
- ans[cnt]=ans[cnt-1];
- for(int i=0;i<k;i++){
- ans[cnt]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- mp[x[i]][y[i]]--;
- ans[cnt]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- if(s[i][j]=='U') x[i]--;
- else if(s[i][j]=='D') x[i]++;
- else if(s[i][j]=='R') y[i]++;
- else if(s[i][j]=='L') y[i]--;
- ans[cnt]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- mp[x[i]][y[i]]++;
- ans[cnt]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
- }
- ++cnt;
- }
- for(int i=0;i<=T;i++){
- printf("%d\n",ans[i]);
- }
- return 0;
- }
os:当时做题的时候队友开的计算几何,这个题看都没看,,,完完全全签到啊呜呜呜

给定数组a和一个数x,问有多少区间的乘积在模这个东西下得数为x。
思路:分两种情况讨论:x==0时,计算包含0的区间即可,注意不仅仅是数组中是0,模那个东西等于0也算;x不等于0时,同样以0为分界,对每一段维护前缀积,用map维护桶即可。
AC Code:
- #include <bits/stdc++.h>
-
- #define INF 0x3f3f3f3f
- typedef long long ll;
- const int N=5e5+5;
- const int mod=998244353;
- ll n,x,b,res,ans;
- ll a[N];
-
- int main(){
- std::ios::sync_with_stdio(false);
- std::cin.tie(0);
- std::cout.tie(0);
- std::cin>>n>>x;
- if(x==0){
- for(int i=1;i<=n;i++){
- std::cin>>b;
- a[i]=b%mod;
- if(a[i]==0) res=i;
- ans+=res;
- }
- }
- else{
- std::map<int,int>mp;
- res=mp[x]=1;
- for(int i=1;i<=n;i++){
- std::cin>>b;
- a[i]=b%mod;
- if(a[i]==0){
- mp.clear();
- res=mp[x]=1;
- }
- else{
- res=res*a[i]%mod;
- ans+=mp[res];
- ++mp[res*x%mod];
- }
- }
- }
- std::cout<<ans<<'\n';
- return 0;
- }
os:学习的师哥队的代码,我还是在某些处理上需要加强啊

给出一面旗子的比例,给出A,B两点的坐标,求旗子其他所有点的坐标。
os:这个题真的是无语,纸质题面和牛客上不一样,,纸质的没有说这个旗子可以旋转,,白费了我们那么长时间,,好叭也是我们不自量力了才会开计算几何题,寄
思路:根据比例计算线段的长度,可以得到点的坐标。对于这个题而言,我们大可以使用原题给的数据按比例缩放后旋转。思路不难,但是非常麻烦。
注:对于关于某点旋转,可以采用矩阵旋转直接带入:

矩阵右乘(x,y)的转置矩阵即可。实际上,我们可以发现,不必考虑顺时针或者逆时针旋转,直接代数,根据角度的正负即可。
AC Code:
- #include <bits/stdc++.h>
-
- #define INF 0x3f3f3f3f
- typedef long long ll;
- typedef long double ld;
- const double PI=acos(-1);
- int t;
- ld xa,ya,xb,yb;
- ld xx[]={
- 30.000000,30.000000,15.000000,16.347084,20.706339,17.179628,18.526712,15.000000,11.473288,12.820372,9.293661,13.652916
- };
- ld yy[]={
- 20.000000,0.000000,16.000000,11.854102,11.854102,9.291796,5.145898,7.708204,5.145898,9.291796,11.854102,11.854102
- };
-
- void init(){
- ld MN=(6*sin(PI*2/5))/(1+sin(PI/10));
- ld PF=MN*sin(PI/10);
- ld OP=6*cos(PI*2/5);
- ld PG=6*sin(PI*2/5);
- ld OF=sqrt(PF*PF+OP*OP);
- //F
- xx[3]=15+PF;
- yy[3]=10+OP;
- //G
- xx[4]=15+PG;
- yy[4]=10+OP;
- //H
- xx[5]=15+OF*cos(PI/10);
- yy[5]=10-OF*sin(PI/10);
- //I
- xx[6]=15+6*sin(PI/5);
- yy[6]=10-6*cos(PI/5);
- //J
- yy[7]=10-OF;
- //K
- xx[8]=15-6*sin(PI/5);
- yy[8]=10-6*cos(PI/5);
- //L
- xx[9]=15-OF*cos(PI/10);
- yy[9]=10-OF*sin(PI/10);
- //M
- xx[10]=15-PG;
- yy[10]=10+OP;
- //N
- xx[11]=15-PF;
- yy[11]=10+OP;
- }
-
- int main(){
- init();
- scanf("%d",&t);
- while(t--){
- scanf("%Lf%Lf%Lf%Lf",&xa,&ya,&xb,&yb);
- xb-=xa,yb-=ya;
- ld sinn=xb,coss=yb;
- for(int i=0;i<12;i++){
- ld sinx=xx[i];
- ld cosx=yy[i];
- ld cosp=cosx*coss-sinx*sinn;
- ld sinp=sinx*coss+cosx*sinn;
- ld ansx=sinp/20+xa;
- ld ansy=cosp/20+ya;
- printf("%.10Lf %.10Lf%c",ansx,ansy,i==11?'\n':' ');
- }
- }
- return 0;
- }
os:学习的wygg队的代码,简洁而且很清楚,tqllllll!!!
先这样吧,能力有限,明年省赛再战!
若有错误请指教,谢谢!