csps模拟73-74

模拟73:

T1:哔~~~~~~~~~~~~~~~~~~~~

sb模拟,然而一个小细节打炸了,不想解释(吐嘈大样例没有右移)。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 int a[10][10],b[10][10],pd[10][10];
  7 int n,m,x,y,z,d,k,v,r;
  8 long long ans;
  9 void add()
 10 {
 11     r=0;
 12     for( int i=1;i<=n;++i)
 13         for( int j=1;j<=n;++j)
 14             if(!a[i][j])++r;
 15     k=1+k%r;
 16     for( int i=1;i<=n;++i)
 17         for( int j=1;j<=n;++j)
 18             if(!a[i][j]){--k;if(!k){a[i][j]=v;return;}}
 19 }
 20 inline bool work0()
 21 {
 22     int ok=0;
 23     for( int i=0;i<=n;++i)
 24         for( int j=0;j<=n;++j)b[i][j]=pd[i][j]=0;
 25     for( int i=1;i<=n;++i)
 26         for( int j=1;j<=n;++j)
 27             if(a[i][j])
 28             {
 29                 b[++b[0][j]][j]=a[i][j];
 30                 if(b[0][j]!=i)ok=1;
 31             }
 32     for( int i=0;i<=n;++i)
 33         for( int j=0;j<=n;++j)a[i][j]=0;
 34     for( int i=1;i<=n;++i)
 35         for( int j=1;j<=n;++j)
 36             if(b[i][j])
 37             {
 38                 a[++a[0][j]][j]=b[i][j];
 39                 if(a[a[0][j]][j]==a[a[0][j]-1][j]&&!pd[a[0][j]-1][j])
 40                 {
 41                     a[a[0][j]][j]=0;
 42                     a[--a[0][j]][j]<<=1;
 43                     pd[a[0][j]][j]=1;
 44                     ans+=a[a[0][j]][j];
 45                     ok=1;
 46                 }
 47             }
 48     if(!ok)return 1;
 49     return 0;
 50 }
 51 inline bool work1()
 52 {
 53     for( int i=0;i<=n;++i)
 54         for( int j=0;j<=n;++j)b[i][j]=a[n-i+1][j];
 55     for( int i=0;i<=n;++i)
 56         for( int j=0;j<=n;++j)a[i][j]=b[i][j];
 57     
 58     if(work0())return 1;
 59     
 60     for( int i=0;i<=n;++i)
 61         for( int j=0;j<=n;++j)b[i][j]=a[n-i+1][j];
 62     for( int i=0;i<=n;++i)
 63         for( int j=0;j<=n;++j)a[i][j]=b[i][j];
 64     return 0;
 65 }
 66 inline bool work2()
 67 {
 68     int ok=0;
 69     for( int i=0;i<=n;++i)
 70         for( int j=0;j<=n;++j)b[i][j]=pd[i][j]=0;
 71     for( int i=1;i<=n;++i)
 72         for( int j=1;j<=n;++j)
 73             if(a[i][j]){
 74                 b[i][++b[i][0]]=a[i][j];
 75                 if(b[i][0]!=j)ok=1;
 76             }
 77     for( int i=0;i<=n;++i)
 78         for( int j=0;j<=n;++j)a[i][j]=0;
 79     for( int i=1;i<=n;++i)
 80         for( int j=1;j<=n;++j)
 81             if(b[i][j])
 82             {
 83                 a[i][++a[i][0]]=b[i][j];
 84                 if(a[i][a[i][0]]==a[i][a[i][0]-1]&&!pd[i][a[i][0]-1])
 85                 {
 86                     a[i][a[i][0]]=0;
 87                     a[i][--a[i][0]]<<=1;
 88                     pd[i][a[i][0]]=1;
 89                     ans+=a[i][a[i][0]];
 90                     ok=1;
 91                 }
 92             }
 93     if(!ok)return 1;
 94     return 0;
 95 }
 96 inline bool work3()
 97 {
 98     int ok=0;
 99     for( int i=0;i<=n;++i)
100         for( int j=0;j<=n;++j)b[i][j]=a[i][n-j+1];
101     for( int i=0;i<=n;++i)
102         for( int j=0;j<=n;++j)a[i][j]=b[i][j];
103     
104     if(work2())return 1;
105     
106     for( int i=0;i<=n;++i)
107         for( int j=0;j<=n;++j)b[i][j]=a[i][n-j+1];
108     for( int i=0;i<=n;++i)
109         for( int j=0;j<=n;++j)a[i][j]=b[i][j];
110     return 0;
111 }
112 void pr()
113 {
114     puts("





































");
115     for(int i=1;i<=n;puts(""),++i)
116         for(int j=1;j<=n;++j)printf("%4d",a[i][j]);
117     puts("");
118 }
119 int main()
120 {
121     srand(time(0));
122     scanf("%d",&n);
123     x=rand()%n+1;y=rand()%n+1;
124     a[x][y]=2;
125     while(1)
126     {
127         pr();k=rand()%233+1;v=2;
128         char c=getchar();
129         while(c!='w'&&c!='a'&&c!='s'&&c!='d')c=getchar();
130         switch(c)
131         {
132             case 'w':{
133                 if(work0()){
134                     puts("Skyh have aked IOI");
135                     return 0;
136                 }
137                 add();
138                 break;
139             }
140             case 's':{
141                 if(work1()){
142                     puts("Skyh have aked IOI");
143                     return 0;
144                 }
145                 add();
146                 break;
147             }
148             case 'a':{
149                 if(work2()){
150                     puts("Skyh have aked IOI");
151                     return 0;
152                 }
153                 add();
154                 break;
155             }
156             case 'd':{
157                 if(work3()){
158                     puts("Skyh have aked IOI");
159                     return 0;
160                 }
161                 add();
162                 break;
163             }
164         }
165     }
166     return 0;
167 }
2048

T2:结论题,dp,数据结构优化,秒切

 1 //反正法证明段数不会大于2。。。
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define ll long long
 7 #define N 100050
 8 using namespace std;
 9 int n;
10 ll ct[N],f[N],dp[N],ans;
11 int lsh[N],ls,a[N];
12 void init()
13 {
14     sort(lsh+1,lsh+n+1);
15     ls=unique(lsh+1,lsh+n+1)-lsh-1;
16     for(int i=1;i<=n;++i)
17         a[i]=lower_bound(lsh+1,lsh+ls+1,a[i])-lsh;
18 }
19 inline int add(int x,long long v)
20 {
21     while(x<=n)
22     {
23         ct[x]=max(ct[x],v);
24         x+=x&-x;
25     }
26 }
27 inline ll ask(int x)
28 {
29     ll ret=0;
30     while(x)
31     {
32         if(ct[x]>ret)ret=ct[x];
33         x-=x&-x;
34     }
35     return ret;
36 }
37 int main()
38 {
39     scanf("%d",&n);
40     for(register int i=1;i<=n;++i)
41     {
42         scanf("%d",&a[i]);
43         lsh[++ls]=a[i];
44     }
45     init();
46     for(register int i=1;i<=n;++i)
47     {
48         f[i]=ask(a[i]-1)+lsh[a[i]];
49         add(a[i],f[i]);
50         if(f[i-1]>f[i])f[i]=f[i-1];
51     }
52     for(register int i=1;i<=n;++i)ct[i]=0;
53     for(register int i=n;i;--i)
54     {
55         dp[i]=ask(a[i]-1)+lsh[a[i]];add(a[i],dp[i]);
56         if(dp[i+1]>dp[i])dp[i]=dp[i+1];
57     }
58     for(register int i=1;i<=n;++i)
59     {
60         ans=max(ans,f[i]+max(f[i],dp[i+1]));
61     }
62     double t=0.5*ans;
63     printf("%.3lf
",t);
64     return 0;
65 }
View Code

T3:神题,对高考数学涉及较多,主要考察三角函数应用。暴力枚举弧度数即可A掉(数据较水,莫要吐嘈细节)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #define N 55
 8 using namespace std;
 9 const int inf=100000;
10 int n,m,fa[N];
11 struct node{
12     int x,y;
13     double a,b;
14     double val,z,ta,ct,si,co;
15     inline void init()
16     {
17         z=sqrt(1.0*a*a+1.0*b*b);
18         ta=1.0*b/a;ct=1.0*a/b;
19         si=1.0*b/z;co=1.0*a/z;
20     }
21     friend bool operator < (const node &c,const node &d){return c.val<d.val;}
22 }q[5555],t;
23 double ans;
24 int getfa(int x)
25 {
26     if(fa[x]==x)return x;
27     return fa[x]=getfa(fa[x]);
28 }
29 int main()
30 {
31     srand(time(0));
32     scanf("%d%d",&n,&m);int ok=1;
33     for(int i=1;i<=m;++i)
34         scanf("%d%d%lf%lf",&q[i].x,&q[i].y,&q[i].a,&q[i].b),q[i].init();
35     random_shuffle(q+1,q+m+1);
36     double a,b;
37     for(double i=1;i<=360;i+=0.7)
38     {
39         a=b=0.0;
40         t.z=1000.0;t.a=t.z*cos(i);t.b=t.z*sin(i);
41         t.init();
42         for(int j=1;j<=m;++j)
43             q[j].val=q[j].z*(t.co*q[j].co+t.si*q[j].si);
44         for(int j=1;j<=n;++j)fa[j]=j;
45         sort(q+1,q+m+1);
46         for(int j=1;j<=m;++j)
47         {
48             if(getfa(q[j].x)==getfa(q[j].y))continue;
49             fa[getfa(q[j].x)]=getfa(q[j].y);
50             a+=q[j].a;b+=q[j].b;
51         }
52         ans=max(ans,sqrt(1ll*a*a+1ll*b*b));
53     }
54     printf("%.6lf
",ans);    
55 }
View Code

正解skyh说挺简单的不用解释。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<cstdlib>
  7 #include<queue>
  8 #define N 55
  9 using namespace std;
 10 const int inf=100000;
 11 int n,m,fa[N];
 12 struct node{
 13     int x,y;
 14     double a,b;
 15     double val,z,ta,ct,si,co;
 16     inline void init()
 17     {
 18         z=sqrt(1.0*a*a+1.0*b*b);
 19         ta=1.0*b/a;ct=1.0*a/b;
 20         si=1.0*b/z;co=1.0*a/z;
 21     }
 22     friend bool operator < (const node &c,const node &d){return c.val<d.val;}
 23 }q[5555],t;
 24 double ans;
 25 int getfa(int x)
 26 {
 27     if(fa[x]==x)return x;
 28     return fa[x]=getfa(fa[x]);
 29 }
 30 inline double Gauss(double x,double y,double xx,double yy)
 31 {
 32     double k,b;
 33     b=yy-y*(xx/x);
 34     b*=x/xx;
 35     k=(y-b)/x;
 36     return k;
 37 }
 38 queue<double>qq;
 39 void work1()
 40 {
 41     double a,b;
 42     for(double i=1;i<=360;i+=0.7)
 43     {
 44         a=b=0.0;
 45         t.z=1000.0;t.a=t.z*cos(i);t.b=t.z*sin(i);
 46         t.init();
 47         for(int j=1;j<=m;++j)
 48             q[j].val=q[j].z*(t.co*q[j].co+t.si*q[j].si);
 49         for(int j=1;j<=n;++j)fa[j]=j;
 50         sort(q+1,q+m+1);
 51         for(int j=1;j<=m;++j)
 52         {
 53             if(getfa(q[j].x)==getfa(q[j].y))continue;
 54             fa[getfa(q[j].x)]=getfa(q[j].y);
 55             a+=q[j].a;b+=q[j].b;
 56         }
 57         ans=max(ans,sqrt(1ll*a*a+1ll*b*b));
 58     }
 59     printf("%.6lf
",ans);    
 60 }
 61 int main()
 62 {
 63     srand(time(0));
 64     scanf("%d%d",&n,&m);int ok=1;
 65     for(int i=1;i<=m;++i)
 66         {scanf("%d%d%lf%lf",&q[i].x,&q[i].y,&q[i].a,&q[i].b),q[i].init();if(q[i].b)ok=0;}
 67     double a,b,tt;
 68     if(ok){work1();return 0;}
 69     for(int i=1;i<=m;++i)
 70     {
 71         for(int j=1;j<=m;++j)
 72         {
 73             if(j==i||q[i].b==q[j].b)continue;
 74             tt=Gauss(q[i].a,q[i].b,q[j].a,q[j].b);
 75             tt=-1.0/tt;
 76             qq.push(tt);
 77         }
 78     }
 79     while(!qq.empty())
 80     {
 81         a=b=0.0;t.a=1.0;t.b=t.a*(qq.front()+1e-3);
 82         t.init();
 83         for(int j=1;j<=m;++j)
 84             q[j].val=q[j].z*(t.co*q[j].co+t.si*q[j].si);
 85         for(int j=1;j<=n;++j)fa[j]=j;
 86         sort(q+1,q+m+1);
 87         for(int j=1;j<=m;++j)
 88         {
 89             if(getfa(q[j].x)==getfa(q[j].y))continue;
 90             fa[getfa(q[j].x)]=getfa(q[j].y);
 91             a+=q[j].a;b+=q[j].b;
 92         }
 93         ans=max(ans,sqrt(1ll*a*a+1ll*b*b));
 94         a=b=0.0;t.a=-1.0;t.b=t.a*(qq.front()+1e-3);qq.pop();
 95         t.init();
 96         for(int j=1;j<=m;++j)
 97             q[j].val=q[j].z*(t.co*q[j].co+t.si*q[j].si);
 98         for(int j=1;j<=n;++j)fa[j]=j;
 99         sort(q+1,q+m+1);
100         for(int j=1;j<=m;++j)
101         {
102             if(getfa(q[j].x)==getfa(q[j].y))continue;
103             fa[getfa(q[j].x)]=getfa(q[j].y);
104             a+=q[j].a;b+=q[j].b;
105         }
106         ans=max(ans,sqrt(1ll*a*a+1ll*b*b));
107     }
108     printf("%.6lf
",ans);    
109 }
正解

其实还可以,不太恶心

模拟74:

(这里用来写脏话)

T1&T3:水题。。。

T2:神题

时间分配:T1+T3=1h,T2=2.5h

得分分布:T1+T3=200pts,T2=30pts

T2:发现玩具构成一棵树,求树高的期望。

比较难想的其实是把新加入的点当作根节点,而不是接到其他节点之后

题解:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define N 250
 7 using namespace std;
 8 inline int read()
 9 {
10     char c=getchar();int s=0;
11     while(c>'9'||c<'0')c=getchar();
12     while(c>='0'&&c<='9')s=s*10+c-'0',c=getchar();
13     return s;
14 }
15 int n=read();
16 const int mod=read();
17 int ans;
18 inline int qpow(int d,int z)
19 {
20     int ret=1;
21     for(;z;z>>=1,d=1ll*d*d%mod)
22         if(z&1)ret=1ll*ret*d%mod;
23     return ret;
24 }
25 int inv[N];
26 int alv;
27 int dp[N][N];
28 int f[N][N];
29 int g[N][N];
30 int main()
31 {
32     inv[0]=1;
33     for(int i=1;i<=n;++i)inv[i]=qpow(i,mod-2);
34     alv=1;
35     for(int i=1;i<n;++i)alv=1ll*alv*inv[i]%mod;
36     dp[1][1]=1;
37     for(int i=2;i<=n;++i){
38         for(int j=1;j<=i;++j){
39             dp[i][j]=1ll*inv[i]*(1ll*dp[i-1][j-1]*(j-1)%mod+1ll*dp[i-1][j]*(i-j)%mod)%mod;
40             if(dp[i][j]>=mod)dp[i][j]-=mod;
41         }
42     }
43     for(int i=0;i<=n;++i)g[1][i]=f[1][i]=g[0][i]=1;
44     for(int i=2;i<=n;++i){
45         for(int j=1;j<n;++j){f[i][j]=g[i-1][j-1];}
46         for(int j=0;j<n;++j){
47             for(int k=1;k<=i;++k){
48                 g[i][j]+=1ll*g[i-k][j]*f[k][j]%mod*dp[i][k]%mod;
49                 if(g[i][j]>=mod)g[i][j]-=mod;
50             }
51         }
52     }
53     for(int i=1;i<n;++i)
54     {
55         ans+=1ll*(f[n][i]-f[n][i-1])*i%mod;
56         if(ans>=mod)ans-=mod;
57         if(ans<0)ans+=mod;
58     }
59     cout<<ans<<endl;
60     return 0;
61 }
View Code

发现题解中给的dp数组dp[i][j]=inv[i];证明好像可以用数学归纳法。

原文地址:https://www.cnblogs.com/loadingkkk/p/11674113.html