混合算法测试

  最近刚讲了最短路,说要考试我以为是考最短路,然而只有一道是最短路...

  数据似乎有一点问题,不管了,反正手工测评都是对的,那现在就来看看题吧。

  Balanced:(此处并没有网址)

  题意概述:$n$  $(n<=50,000)$头牛排成一排,给定每头牛的位置,有两种种族,选出一个尽量长的区间使得这个区间内两种牛的数量相等。

  首先可以想到枚举...前缀和...然而还是$O(N^2)$的复杂度,很显然是过不了的。思考一下前缀和的做法,用两个数组分别表示两种牛数量的前缀和。当$a[j]-a[i-1]=b[j]-b[i-1]$时,$x[j]-x[i]$就是一个合法的答案了。那对这个式子进行移项:$a[j]-b[j]=a[i-1]-b[i-1]$,所以可以再开一个数组表示$x[i]=a[i]-b[i]$,如果两个位置的$x$相同,就是一个合法的答案,而且区间越长答案一定更优,所以只需要保存每个$x$出现的第一次和最后一次位置,统计答案时取max就可以了。注意$x$数组可以出现负数,所以将整个数组同时加上$n$就可以避免负数了。

  
 1 // shzr
 2 
 3 # include <cstdio>
 4 # include <iostream>
 5 # include <algorithm>
 6 # include <cstring>
 7 
 8 using namespace std;
 9 
10 const int maxn=50009;
11 int n,s1[maxn],s2[maxn],ans,x[maxn],minn[maxn*3],maxx[maxn*3];
12 struct co
13 {
14     int id,x;
15 }a[maxn];
16 bool cmp(co a,co b)
17 {
18     return a.x<b.x;
19 }
20 
21 int main()
22 {
23     scanf("%d",&n);
24     memset(minn,127,sizeof(minn));
25     for (int i=1;i<=n;++i)
26         scanf("%d%d",&a[i].id,&a[i].x);
27     sort(a+1,a+1+n,cmp);
28     minn[0]=0;
29     for (int i=1;i<=n;++i)
30     {
31         if(a[i].id==0) s1[i]++;
32         if(a[i].id==1) s2[i]++;
33         s1[i]+=s1[i-1];
34         s2[i]+=s2[i-1];
35         x[i]=s1[i]-s2[i];
36         minn[ x[i]+n+2 ]=min(minn[ x[i]+n+2 ],i);
37         maxx[ x[i]+n+2 ]=max(maxx[ x[i]+n+2 ],i);
38     }
39     for (int i=0;i<=2*n+2;++i)
40     {
41         if(maxx[i]==0||minn[i]>n) continue;
42         if(maxx[i]==minn[i]) continue;
43         ans=max(ans,a[ maxx[i] ].x-a[ minn[i]+1 ].x);
44     }
45     printf("%d",ans);
46     return 0;
47 }
Balanced

  找礼物:(此处依旧没有网址)

  题意概述:

  

  这道题目非常简单...根据距离排个序再扫一遍就做完了。还有一个问题是精度,因为保留四位小数且是截断小数,所以可以将距离乘上一万存进整型变量里。

  
 1 //shzr
 2 
 3 # include <cstdio>
 4 # include <iostream>
 5 # include <cmath>
 6 # include <algorithm>
 7 # include <cstring>
 8 # include <string>
 9 
10 using namespace std;
11 
12 int n,k;
13 long long x,y;
14 struct gif
15 {
16     string nam;
17     long long len;
18     int rk;    
19 }a[100009];
20 
21 bool cmp(gif a,gif b)
22 {
23     if(a.len==b.len)
24         return a.rk<b.rk;
25     return a.len<b.len;
26 }
27 
28 int main()
29 {
30     scanf("%d%d",&n,&k);
31     for (int i=1;i<=n;++i)
32     {
33         cin>>a[i].nam;
34         scanf("%lld%lld",&x,&y);
35         a[i].len=(long long)(sqrt(x*x+y*y)*10000);
36         a[i].rk=i;
37     }
38     sort(a+1,a+1+n,cmp);
39     int ans=0,pos=1;
40     long long x=0;
41     for (int i=1;i<=k-1;++i)
42     {
43         x=a[pos].len;
44         while(a[pos].len==x&&pos<=n)
45             pos++;
46     }
47     if(pos==n+1)
48     {
49         printf("555…");
50     }
51     else
52     {
53         x=a[pos].len;
54         for (int i=pos;i<=n;++i)
55         {
56             if(a[i].len==x) ans++;
57             else break;
58         }
59         printf("%lld %d\n",x/10000,ans);
60         for (int i=pos;i<=n;++i)
61         {
62             if(a[i].len==x) cout<<a[i].nam<<endl;
63             else break;
64         }
65     }
66     return 0;
67 }
找礼物

  Game:(还是没有网址)

  和四子连棋有一点像的状压搜索题。

  
 1 //shzr
 2 
 3 # include <cstdio>
 4 # include <iostream>
 5 
 6 using namespace std;
 7 
 8 const int dx[]={-1,0,0,1};
 9 const int dy[]={0,1,-1,0};
10 int no,beg,en,x,h=1,t=0;
11 bool vis[700000];
12 int q[6000000];
13 int b[6000000];
14 int a[5][5];
15 
16 void ad(int x)
17 {
18     for (int i=4;i>=1;--i)
19         for (int j=4;j>=1;--j)
20         {
21             a[i][j]=x%2;
22             x/=2;
23         }
24 }
25 
26 int pul()
27 {
28     int ans=0;
29     for (int i=1;i<=4;++i)
30         for (int j=1;j<=4;++j)
31             ans=(ans<<1)+a[i][j];
32     return ans;
33 }
34 
35 int bfs(int beg)
36 {
37     vis[beg]=true;
38     q[++t]=beg;
39     b[t]=0;
40     while (h<=t)
41     {
42         x=q[h];
43         if(x==en) return b[h];
44         ad(x);
45         for (int i=1;i<=4;++i)
46             for (int j=1;j<=4;++j)
47                 for (int z=0;z<4;++z)
48                 {
49                     int xx=i+dx[z];
50                     int yy=j+dy[z];
51                     if(xx<1||xx>4||yy<1||yy>4) 
52                         continue;
53                     if(a[xx][yy]==a[i][j]) continue;
54                     swap(a[xx][yy],a[i][j]);
55                     no=pul();
56                     if(vis[no]==false)
57                     {
58                         vis[no]=true;
59                         q[++t]=no;
60                         b[t]=b[h]+1;
61                     }
62                     swap(a[xx][yy],a[i][j]);
63                 }
64         h++;
65     }
66     return -1;
67 }
68 
69 int main()
70 {
71     for (int i=1;i<=4;++i)
72         for (int j=1;j<=4;++j)
73         {
74             scanf("%1d",&x);
75             beg=(beg<<1)+x;
76         }
77     for (int i=1;i<=4;++i)
78         for (int j=1;j<=4;++j)
79         {
80             scanf("%1d",&x);
81             en=(en<<1)+x;
82         }
83     printf("%d",bfs(beg));
84     return 0;
85 }
Game

  Car的旅行路线:https://www.luogu.org/problemnew/show/P1027

   一直觉得很麻烦不想做的题出现在了考试里...那只好做一做了。其实就是把所有边连上以后跑最短路。

  
  1 //shzr
  2 
  3 # include <cstdio>
  4 # include <iostream>
  5 # include <cmath>
  6 # include <cstring>
  7 # include <queue>
  8 
  9 using namespace std;
 10 
 11 int co,s,t,A,B,firs[500],h=0;
 12 struct nod
 13 {
 14     int x,y;
 15 }a[500];
 16 bool vis[500];
 17 double d[500];
 18 typedef pair<double,int> pii;
 19 priority_queue <pii,vector<pii>,greater<pii> > q;
 20 struct edge
 21 {
 22     int nex,too;
 23     double len;
 24 }g[500000];
 25 
 26 void add(int x,int y,double c)
 27 {
 28     g[++h].too=y;
 29     g[h].nex=firs[x];
 30     firs[x]=h;
 31     g[h].len=c;
 32     g[++h].too=x;
 33     g[h].nex=firs[y];
 34     firs[y]=h;
 35     g[h].len=c;
 36 }
 37 
 38 void find_four(int i)
 39 {
 40     nod A=a[4*i+1],B=a[4*i+2],C=a[4*i+3],D;
 41     long long la,lb,lc;
 42     la=(B.x-C.x)*(B.x-C.x)+(B.y-C.y)*(B.y-C.y);
 43     lb=(A.x-C.x)*(A.x-C.x)+(A.y-C.y)*(A.y-C.y);
 44     lc=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
 45     if(la+lb==lc)
 46     {
 47         D.x=B.x-C.x+A.x;
 48         D.y=B.y-C.y+A.y;
 49     }
 50     if(la+lc==lb)
 51     {
 52         D.x=-B.x+C.x+A.x;
 53         D.y=-B.y+C.y+A.y;
 54     }
 55     if(lb+lc==la)
 56     {
 57         D.x=B.x+C.x-A.x;
 58         D.y=B.y+C.y-A.y;
 59     }
 60     a[4*i+4]=D;
 61 }
 62 
 63 void dij(int s)
 64 {
 65     memset(d,127,sizeof(d));
 66     d[s]=0;
 67     q.push(make_pair(d[s],s));
 68     int j,beg;
 69     while (q.size())
 70     {
 71         beg=q.top().second;
 72         q.pop();
 73         if(vis[beg]) continue;
 74         vis[beg]=true;
 75         for (int i=firs[beg];i;i=g[i].nex)
 76         {
 77             j=g[i].too;
 78             if(d[beg]+g[i].len>=d[j]) continue;
 79             d[j]=d[beg]+g[i].len;
 80             q.push(make_pair(d[j],j));
 81         }
 82     }
 83 }
 84 
 85 int main()
 86 {
 87     scanf("%d%d%d%d",&s,&t,&A,&B);
 88     for (int i=0;i<s;++i)
 89     {
 90         scanf("%d%d%d%d%d%d",&a[4*i+1].x,&a[4*i+1].y,&a[4*i+2].x,&a[4*i+2].y,&a[4*i+3].x,&a[4*i+3].y);
 91         scanf("%d",&co);
 92         find_four(i);
 93         for (int m=1;m<=4;++m)
 94             for (int n=m+1;n<=4;++n)
 95                 add(4*i+m,4*i+n,co*sqrt((a[4*i+m].x-a[4*i+n].x)*(a[4*i+m].x-a[4*i+n].x)+(a[4*i+m].y-a[4*i+n].y)*(a[4*i+m].y-a[4*i+n].y)));
 96         for (int j=1;j<=4;++j)
 97             for (int k=1;k<=4*i;++k)
 98                 add(4*i+j,k,sqrt((a[4*i+j].x-a[k].x)*(a[4*i+j].x-a[k].x)+(a[4*i+j].y-a[k].y)*(a[4*i+j].y-a[k].y))*t);
 99     }
100     for (int i=1;i<=4;++i)
101     {
102         add(0,(A-1)*4+i,0);
103         add(s*4+5,(B-1)*4+i,0);
104     }
105     dij(0);
106     printf("%.1lf",d[s*4+5]);
107     return 0;
108 }
Car的旅行路线

 ---shzr

 

猜你喜欢

转载自www.cnblogs.com/shzr/p/9294269.html