csps模拟测试7273简单的操作小P的2048小P的单调数列小P的生成树

题面:https://www.cnblogs.com/Juve/articles/11678564.html

简单的操作:

考场上sb了,没看出来

如果有奇环一定不能缩成一条链,判掉奇环后就是bfs最短路了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int MAXN=1005;
 8 const int MAXM=1e5+5;
 9 int n,m,col[MAXN],tot=0,ans=0,bel[MAXN],res[MAXN];
10 int to[MAXM<<1],nxt[MAXM<<1],pre[MAXN],cnt=1;
11 void add(int u,int v){
12     ++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
13 }
14 bool dfs(int x,int c){
15     col[x]=c,bel[x]=tot;
16     for(int i=pre[x];i;i=nxt[i]){
17         int y=to[i];
18         if(col[y]==c) return 0;
19         else if((!col[y])&&(!dfs(y,3-c))) return 0;
20     }
21     return 1;
22 }
23 int dis[MAXN];
24 void bfs(int st){
25     memset(dis,0,sizeof(dis));
26     queue<int>q;
27     dis[st]=1;
28     q.push(st);
29     while(!q.empty()){
30         int x=q.front();
31         q.pop();
32         for(int i=pre[x];i;i=nxt[i]){
33             int y=to[i];
34             if(dis[y]==0){
35                 dis[y]=dis[x]+1;
36                 q.push(y);
37             }
38         }
39     }
40 }
41 int main(){
42     scanf("%d%d",&n,&m);
43     for(int i=1,u,v;i<=m;++i){
44         scanf("%d%d",&u,&v);
45         add(u,v),add(v,u);
46     }
47     for(int i=1;i<=n;++i){
48         if(!col[i]){
49             ++tot;
50             if(!dfs(i,1)){
51                 ans=-1;
52                 break;
53             }
54         }
55     }
56     if(ans==-1){
57         printf("%d\n",ans);
58         return 0;
59     }
60     for(int i=1;i<=n;++i){
61         bfs(i);
62         for(int j=1;j<=n;++j){
63             res[bel[i]]=max(res[bel[i]],dis[j]-1);
64         }
65     }
66     for(int i=1;i<=tot;++i){
67         ans+=res[i];
68     }
69     printf("%d\n",ans);
70     return 0;
71 }
View Code

2048:

话说我不会2048考场上是不是爆0了?

就是模拟

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 int n,m,mp[10][10],ans=0;
  7 bool flag=0,vis[10][10];
  8 int get(){
  9     int res=0;
 10     for(int i=1;i<=n;++i){
 11         for(int j=1;j<=n;++j)
 12             res+=(mp[i][j]==0);
 13     }
 14     return res;
 15 }
 16 void put(int pos,int val){
 17     for(int i=1;i<=n;++i){
 18         for(int j=1;j<=n;++j){
 19             if(mp[i][j]!=0) continue;
 20             --pos;
 21             if(pos==0){
 22                 mp[i][j]=val;
 23                 return ;
 24             }
 25         }
 26     }
 27 }
 28 void mergeup(){
 29     for(int i=2;i<=n;++i){
 30         for(int j=1;j<=n;++j){
 31             if(mp[i][j]==0) continue;
 32             int p=i-1,k=mp[i][j];
 33             while(p>0&&mp[p][j]==0) mp[p][j]=k,mp[p+1][j]=0,--p;
 34             if(p!=i-1) flag=1;
 35             if(vis[p][j]==0&&mp[p+1][j]==mp[p][j]) mp[p][j]<<=1,mp[p+1][j]=0,flag=vis[p][j]=1,ans+=mp[p][j];
 36         }
 37     }
 38 }
 39 void up(){
 40     for(int i=2;i<=n;++i){
 41         for(int j=1;j<=n;++j){
 42             if(mp[i][j]==0) continue;
 43             int p=i-1,k=mp[i][j];
 44             while(p>0&&mp[p][j]==0) mp[p][j]=k,mp[p+1][j]=0,--p;
 45             if(p!=i-1) flag=1;
 46         }
 47     }
 48 }
 49 void mergedown(){
 50     for(int i=n-1;i>=1;--i){
 51         for(int j=1;j<=n;++j){
 52             if(mp[i][j]==0) continue;
 53             int p=i+1,k=mp[i][j];
 54             while(p<=n&&mp[p][j]==0) mp[p][j]=k,mp[p-1][j]=0,++p;
 55             if(p!=i+1) flag=1;
 56             if(vis[p][j]==0&&mp[p-1][j]==mp[p][j]) mp[p][j]<<=1,mp[p-1][j]=0,flag=vis[p][j]=1,ans+=mp[p][j];
 57         }
 58     }
 59 }
 60 void down(){
 61     for(int i=n-1;i>=1;--i){
 62         for(int j=1;j<=n;++j){
 63             if(mp[i][j]==0) continue;
 64             int p=i+1,k=mp[i][j];
 65             while(p<=n&&mp[p][j]==0) mp[p][j]=k,mp[p-1][j]=0,++p;
 66             if(p!=i+1) flag=1;
 67         }
 68     }
 69 }
 70 void mergeleft(){
 71     for(int j=2;j<=n;++j){
 72         for(int i=1;i<=n;++i){
 73             if(mp[i][j]==0) continue;
 74             int p=j-1,k=mp[i][j];
 75             while(p>0&&mp[i][p]==0) mp[i][p]=k,mp[i][p+1]=0,--p;
 76             if(p!=j-1) flag=1;
 77             if(vis[i][p]==0&&mp[i][p]==mp[i][p+1]) mp[i][p]<<=1,mp[i][p+1]=0,flag=vis[i][p]=1,ans+=mp[i][p];
 78         }
 79     }
 80 }
 81 void left(){
 82     for(int j=2;j<=n;++j){
 83         for(int i=1;i<=n;++i){
 84             if(mp[i][j]==0) continue;
 85             int p=j-1,k=mp[i][j];
 86             while(p>0&&mp[i][p]==0) mp[i][p]=k,mp[i][p+1]=0,--p;
 87             if(p!=j-1) flag=1;
 88         }
 89     }
 90 }
 91 void mergeright(){
 92     for(int j=n-1;j>=1;--j){
 93         for(int i=1;i<=n;++i){
 94             if(mp[i][j]==0) continue;
 95             int p=j+1,k=mp[i][j];
 96             while(p<=n&&mp[i][p]==0) mp[i][p]=k,mp[i][p-1]=0,++p;
 97             if(p!=j+1) flag=1;
 98             if(vis[i][p]==0&&mp[i][p]==mp[i][p-1]) mp[i][p]<<=1,mp[i][p-1]=0,flag=vis[i][p]=1,ans+=mp[i][p];
 99         }
100     }
101 }
102 void right(){
103     for(int j=n-1;j>=1;--j){
104         for(int i=1;i<=n;++i){
105             if(mp[i][j]==0) continue;
106             int p=j+1,k=mp[i][j];
107             while(p<=n&&mp[i][p]==0) mp[i][p]=k,mp[i][p-1]=0,++p;
108             if(p!=j+1) flag=1;
109         }
110     }
111 }
112 int main(){
113     scanf("%d%d",&n,&m);
114     int xx1,yy1,vv1,xx2,yy2,vv2;
115     scanf("%d%d%d%d%d%d",&xx1,&yy1,&vv1,&xx2,&yy2,&vv2);
116     mp[xx1][yy1]=vv1,mp[xx2][yy2]=vv2;
117     for(int i=1,d,k,v;i<=m;++i){
118         scanf("%d%d%d",&d,&k,&v);
119         memset(vis,0,sizeof(vis));
120         flag=0;
121         if(d==0) mergeup(),up();
122         if(d==1) mergedown(),down();
123         if(d==2) mergeleft(),left();
124         if(d==3) mergeright(),right();
125         if(!flag){
126             printf("%d\n%d\n",i-1,ans);
127             return 0;
128         }
129         put(k%get()+1,v);
130     }
131     printf("%d\n%d\n",m,ans);
132     return 0;
133 }
View Code

数列:

可以证明最优答案要么是单增,要么先增后减

然后就是最长上升子序列了,好像也不太一样,都差不多

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 using namespace std;
 7 const int MAXN=1e5+5;
 8 int n,a[MAXN],b[MAXN],f[MAXN],g[MAXN],mx=0;
 9 int lsh[MAXN];
10 double ans=0.0;
11 struct BIT{
12     int c[MAXN];
13     int lowbit(int x){
14         return x&(-x);
15     }
16     int update(int pos,int val){
17         for(int i=pos;i<=mx;i+=lowbit(i)){
18             c[i]=max(c[i],val);
19         }
20     }
21     int query(int pos){
22         int res=0;
23         for(int i=pos;i>0;i-=lowbit(i)){
24             res=max(res,c[i]);
25         }
26         return res;
27     }
28 }t1,t2;
29 double max(double a,double b){
30     return a>b?a:b;
31 }
32 signed main(){
33     scanf("%lld",&n);
34     for(int i=1;i<=n;++i){
35         scanf("%lld",&a[i]);
36         lsh[i]=a[i];
37     }
38     sort(lsh+1,lsh+n+1);
39     mx=unique(lsh+1,lsh+n+1)-lsh-1;
40     for(int i=1;i<=n;++i) b[i]=lower_bound(lsh+1,lsh+mx+1,a[i])-lsh;
41     for(int i=1;i<=n;++i){
42         f[i]=t1.query(b[i]-1)+a[i];
43         g[i]=t2.query(b[n-i+1]-1)+a[n-i+1];
44         t1.update(b[i],f[i]);
45         t2.update(b[n-i+1],g[i]);
46     }
47     for(int i=1;i<=n;++i)
48         ans=max(ans,max(f[i],(f[i]+g[n-i+1]-a[i])/2.0));
49     printf("%0.3lf\n",ans);
50     return 0;
51 }
View Code

生成树:

连虚数都出来了。。。

把每一个虚数看作向量,枚举角度更新答案

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int MAXN=55;
 8 const int MAXM=205;
 9 int n,m,fa[MAXN];
10 double ans=0.0,xx,yy;
11 int find(int x){
12     return fa[x]=(fa[x]==x?x:find(fa[x]));
13 }
14 struct node{
15     int fr,to;
16     double a,b;
17     friend bool operator < (node p,node q){
18         return p.a*xx+p.b*yy<q.a*xx+q.b*yy;
19     }
20 }e[MAXM];
21 double kruskal(){
22     int vala=0,valb=0,sum=0;
23     for(int i=1;i<=n;++i) fa[i]=i;
24     sort(e+1,e+m+1);
25     for(int i=1;i<=m;++i){
26         int x=find(e[i].fr),y=find(e[i].to);
27         if(x!=y){
28             fa[x]=y;
29             ++sum,vala+=e[i].a,valb+=e[i].b;
30             if(sum==n-1) break;
31         }
32     }
33     return sqrt(vala*vala+valb*valb);
34 }
35 int main(){
36     scanf("%d%d",&n,&m);
37     for(int i=1,u,v;i<=m;++i){
38         double a,b;
39         scanf("%d%d%lf%lf",&u,&v,&a,&b);
40         e[i]=(node){u,v,a,b};
41     }
42     for(double i=0.0;i<=63.00;i+=0.01){
43         xx=sin(i),yy=cos(i);
44         ans=max(ans,kruskal());
45     }
46     printf("%0.6lf\n",ans);
47     return 0;
48 }
View Code

 

posted @ 2019-10-15 16:39  xukl21  阅读(260)  评论(0编辑  收藏  举报