码迷,mamicode.com
首页 > 其他好文 > 详细

*湖南师范大学第五届大学生计算机程序设计竞赛(AKing)

时间:2014-06-10 10:40:22      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:c   style   class   blog   code   a   

【比赛链接】:http://acm.hunnu.edu.cn/online/?action=problem&type=list&courseid=132

A:跑得快计数程序

【题解】:细心点,巧妙乘2处理四舍五入,简单模拟

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <set>
 7 
 8 #define LL long long
 9 using namespace std;
10 int A[5],B[5];
11 int main(){
12     int t;
13     cin>>t;
14     while(t--){
15         int N;
16         cin>>N;
17         memset(A,0,sizeof(A));
18         memset(B,0,sizeof(B));
19         for(int i=1;i<=N;i++){
20             int a[5];
21             cin>>a[1]>>a[2]>>a[3]>>a[4];
22             int p=0;
23             for(int i=1;i<=4;i++)
24             if (a[i]>0){
25                 if (a[i]==12) B[i]=12;
26                 else B[i]=(int)(a[i]*0.4+0.5);
27             }else if (a[i]==0) p=i;
28 
29             B[p]=0;
30             for(int i=1;i<=4;i++){
31                 if (i!=p) B[p]+=B[i];
32             }
33             for(int i=1;i<=4;i++){
34                 if (i!=p) B[i]=-B[i];
35             }
36             for(int i=1;i<=4;i++) A[i]+=B[i];
37         }
38         for(int i=1;i<=4;i++){
39             if (i==4) cout<<A[i]<<endl;else cout<<A[i]<<" ";
40         }
41     }
42 }
View Code

B:棋盘游戏

【题解】:

【代码】:

C:区间求最值

【题解】:10^6个数字,RMQ[10^6][20]根本存不下,所以用线段树,虽然时间较慢,但是空间足够。比赛每做出这道题,说明对这两种方法没有掌握。

预处理比较精妙,建树递归O(n)算法

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 
 5 using namespace std;
 6 
 7 int pris[1000005];
 8 int A[1000005];
 9 int maxv[1000005<<2];
10 int t,n,q;
11 void init(){
12     memset(pris,0,sizeof(pris));
13     for(int i=1;i<=1000000;i++){
14         for(int j=i;j<=1000000;j+=i){
15             pris[j]++;
16         }
17     }
18     return ;
19 }
20 void builtTree(int o,int l,int r){//递归建树
21     if (l==r){
22         maxv[o]=A[l];
23         return;//记得return
24     }
25     int m=l+(r-l)/2;
26     builtTree(o<<1,l,m);
27     builtTree(o<<1|1,m+1,r);
28     maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);
29     return ;
30 }
31 int Query(int ql,int qr,int o,int l,int r){
32     if (ql<=l && r<=qr) return maxv[o];
33     int m=l+(r-l)/2;
34     int ans = -1;
35     if (ql<=m) ans=max(ans,Query(ql,qr,o<<1,l,m));
36     if (m+1<=qr) ans=max(ans,Query(ql,qr,o<<1|1,m+1,r));
37     return ans;
38 }
39 int main(){
40     init();
41     scanf("%d",&t);
42     while(t--){
43         scanf("%d",&n);
44         for(int i=1;i<=n;i++){
45             int x;
46             scanf("%d",&x);
47             A[i]=pris[x];
48         }
49         builtTree(1,1,n);//建树
50         scanf("%d",&q);
51         while(q--){
52             int l,r;
53             scanf("%d%d",&l,&r);
54             int ans=Query(l,r,1,1,n);
55             printf("%d\n",ans);
56         }
57     }
58     return 0;
59 }
View Code

D:数组求和问题

【题解】:简单分析题意,直接暴力,数据量是唬人的,注意下标处理,样例有点问题

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #define LL long long
 7 using namespace std;
 8 int t,n,m,s,p;
 9 int a[100005];
10 
11 int main(){
12     scanf("%d",&t);
13     for(int cas=1;cas<=t;cas++){
14         scanf("%d%d%d%d",&n,&m,&s,&p);
15         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
16         int ans=0;
17         for(int st=1;st+(m-1)*p<=n;st++){
18             int tt=0;
19             for(int i=st;i<=st+(m-1)*p;i+=p) tt+=a[i];
20             if (tt==s) ans++;
21         }
22         printf("case %d:%d\n",cas,ans);
23     }
24     return 0;
25 }
View Code

E:推箱子

【题解】:枚举,总共的移动方法就那么两种,特殊情况,目的地和箱子和人在一条直线上,人不能直接穿过箱子

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <set>
 7 #include <math.h>
 8 #define maxn 105
 9 #define eps 0.0000001
10 
11 #define LL long long
12 using namespace std;
13 
14 int abss(int x1,int yy1,int x2,int y2){
15     return abs(x1-x2)+abs(yy1-y2);
16 }
17 int x1,yy1,x2,y2,x3,y3;
18 int main(){
19     while(~scanf("%d%d%d%d%d%d",&x1,&yy1,&x2,&y2,&x3,&y3)){
20         if (x2==x3 && y2==y3){
21             cout<<0<<endl;
22             continue;
23         }
24         int ans=99999999,m;
25         if (y2==y3){
26             if (x2<x3){
27                 m=abss(x2-1,y2,x1,yy1)+x3-x2;
28                 if (x1>x2 && yy1==y2) m+=2;
29                 ans=min(ans,m);
30             }
31             if (x2>x3){
32                 m=abss(x2+1,y2,x1,yy1)+x2-x3;
33                 if (x1<x2 && yy1==y2) m+=2;
34                 ans=min(ans,m);
35             }
36         }
37         if (x2==x3){
38             if (y2<y3){
39                 m=abss(x2,y2-1,x1,yy1)+y3-x2;
40                 if (yy1>y2 && x1==x2) m+=2;
41                 ans=min(ans,m);
42             }
43             if (y2>y3){
44                 m=abss(x2,y2+1,x1,yy1)+y2-y3;
45                 if (yy1<y2 && x1==x2) m+=2;
46                 ans=min(ans,m);
47             }
48         }
49         if (x2<x3 && y2<y3){
50             m=abss(x1,yy1,x2-1,y2)+abs(x3-x2)+2+abs(y3-y2);
51             ans=min(ans,m);
52             m=abss(x1,yy1,x2,y2-1)+abs(x3-x2)+2+abs(y3-y2);
53             ans=min(ans,m);
54         }
55         if (x2<x3 && y2>y3){
56             m=abss(x1,yy1,x2-1,y2)+abs(x3-x2)+2+abs(y3-y2);
57             ans=min(ans,m);
58             m=abss(x1,yy1,x2,y2+1)+abs(x3-x2)+2+abs(y3-y2);
59             ans=min(ans,m);
60         }
61         if (x2>x3 && y2<y3){
62             m=abss(x1,yy1,x2+1,y2)+abs(x3-x2)+2+abs(y3-y2);
63             ans=min(ans,m);
64             m=abss(x1,yy1,x2,y2-1)+abs(x3-x2)+2+abs(y3-y2);
65             ans=min(ans,m);
66         }
67         if (x2>x3 && y2>y3){
68             m=abss(x1,yy1,x2+1,y2)+abs(x3-x2)+2+abs(y3-y2);
69             ans=min(ans,m);
70             m=abss(x1,yy1,x2,y2+1)+abs(x3-x2)+2+abs(y3-y2);
71             ans=min(ans,m);
72         }
73         printf("%d\n",ans);
74     }
75     return 0;
76 }
View Code

F:信封问题

【题解】:

【代码】:

G:修路

【题解】:二分(答案:最长的路)+重新见图+最小生成树(判定生成了一棵完整的树)

容易错的地方:1、二分后也要判断F(L)是否可形成一颗完整的树   2、开始我忘记Merge(u,v),逗了 3、二分用for控制次数好些

【代码】:

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <set>
 7 #include <math.h>
 8 #define maxn 105
 9 #define eps 0.0000001
10 
11 #define LL long long
12 using namespace std;
13 int n,m,M,y;
14 
15 struct E{
16     int u,v,c,d;
17     bool operator < (const E& X)const{
18         return c<X.c;
19     }
20 }e1[100005*2],e2[100005*2];
21 int p[10005];
22 void init(){
23     for(int i=1;i<=n;i++) p[i]=i;
24     return;
25 }
26 int findx(int x){
27     if (p[x]==x) return x;else return p[x]=findx(p[x]);
28 }
29 void merge(int x,int y){
30     int px=findx(x);
31     int py=findx(y);
32     p[px]=py;
33 }
34 bool F(int x)//最长路
35 {
36     init();
37     int cnt=0;
38     for(int i=0;i<M;i++){
39         if (e1[i].d<=x) {
40             e2[cnt++]=e1[i];
41         }
42     }
43 //    cout<<"M="<<M<<endl;
44     sort(e2,e2+cnt);
45 //    for(int i=0;i<cnt;i++) e2[i].print();
46     int t=0,l=0;
47     bool vis[10005];
48     memset(vis,0,sizeof(vis));
49     for(int i=0;i<cnt;i++){
50         int u=e2[i].u,v=e2[i].v,c=e2[i].c;
51         if (findx(u)==findx(v)) continue;
52         merge(u,v);
53         l+=c;
54         if (!vis[u]){
55             vis[u]=true;
56             t++;
57         }
58         if (!vis[v]){
59             vis[v]=true;
60             t++;
61         }
62         if (t==n) break;
63     }
64 //    cout<<"t="<<t<<","<<"l="<<l<<endl;
65     if (t>=n && l<=y ) return true;else return false;
66 }
67 int main(){
68     while(~scanf("%d%d%d",&n,&m,&y)){
69         M=0;
70         int Maxd = -1;
71         for(int i=0;i<m;i++) {
72             int u,v,c,d;
73             scanf("%d%d%d%d",&u,&v,&c,&d);
74             if (u!=v) {
75                 e1[M++]=(E){u,v,c,d};
76                 e1[M++]=(E){v,u,c,d};
77             }
78             Maxd=max(Maxd,d);
79         }
80         if (m==0 || m<n-1) {
81             cout<<"-1"<<endl;
82             continue;
83         }
84         if (!F(Maxd)) {
85             cout<<"-1"<<endl;
86             continue;
87         }
88         int L=0,R=Maxd+1;
89         for(int t=1;t<=45;t++){
90             int M=L+(R-L)/2;
91             if (F(M)) R=M;else L=M+1;
92         }
93         if (F(L)) cout<<L<<endl;else cout<<"-1"<<endl;
94     }
95     return 0;
96 }
View Code

H:找数游戏

【题解】:

【代码】:

I:找数字2

【题解】:10^7个数字,是我不够机智,还用神马multi-set,果断超空间,其实就是异或运算性质的运用

【代码】:

bubuko.com,布布扣View Code

J:高校围墙

【题解】:看了很长时间才看出宿舍外围是什么意思,汗,计算凸包+多边形面积,注意1个点、2个点、多点共线的特例,就是W在这些上面了。

以后做题一定要注意这几点

【代码】:

bubuko.com,布布扣
  1 #include <iostream>
  2 #include <string.h>
  3 #include <stdio.h>
  4 #include <algorithm>
  5 #include <stdlib.h>
  6 #include <set>
  7 #include <math.h>
  8 #define maxn 105
  9 #define eps 0.0000001
 10 
 11 #define LL long long
 12 using namespace std;
 13 struct Point
 14 {
 15     double x,y;
 16     bool operator<(const Point& p) const//注意:按照逆时针旋转
 17     {
 18         if (fabs(x-p.x)<eps) return y<p.y;//注意,这里eps一定要加,不然,不能正常排序
 19         else return x<p.x;
 20     }
 21 } P1[maxn],P2[maxn];
 22 
 23 typedef Point Vector;
 24 
 25 bool operator==(Point A,Point B)
 26 {
 27     if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
 28     else return false;
 29 }
 30 Vector operator-(Point A,Point B)//表示A指向B
 31 {
 32     return (Vector){A.x-B.x,A.y-B.y};
 33 }
 34 Vector operator*(Vector A,double k)
 35 {
 36     return (Vector){A.x*k,A.y*k};
 37 }
 38 Vector operator+(Point A,Point B)//表示A指向B
 39 {
 40     return (Vector){B.x+A.x,B.y+A.y};
 41 }
 42 double Cross(Vector A,Vector B)
 43 {
 44     return A.x*B.y-A.y*B.x;
 45 }
 46 double Area2(Point A,Point B,Point C)
 47 {
 48     return Cross(B-A,C-A);
 49 }
 50 int ConvexHull(Point *p, int n, Point* ch)         //求凸包
 51 {
 52     sort(p, p + n);//先按照x,再按照y
 53     int m = 0;
 54     for(int i = 0; i < n; i++)
 55     {
 56         while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
 57         ch[m++] = p[i];
 58     }
 59     int k = m;
 60     for(int i = n-2; i >= 0; i--)
 61     {
 62         while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--;
 63         ch[m++] = p[i];
 64     }
 65     if(n > 1) m--;
 66     return m;
 67 }
 68 double solve(Point p[],int n){
 69     double ans=0;
 70     for(int i=1;i<n;i++){
 71         ans+=sqrt((p[i].x-p[i-1].x)*(p[i].x-p[i-1].x)+(p[i].y-p[i-1].y)*(p[i].y-p[i-1].y)+0.0);
 72     }
 73     ans+=sqrt((p[n-1].x-p[0].x)*(p[n-1].x-p[0].x)+(p[n-1].y-p[0].y)*(p[n-1].y-p[0].y)+0.0);
 74     return ans;
 75 }
 76 int t,n,cnt1,cnt2;
 77 int main()
 78 {
 79     int cas=0;
 80     while(cin>>n && n){
 81         cas++;
 82         cnt1=0;
 83         for(int i=0;i<n;i++)
 84         {
 85             LL x,y;
 86             cin>>x>>y;
 87             P1[cnt1++]=(Point){x+0.0,y+0.0};
 88         }
 89         cnt2=ConvexHull(P1,cnt1,P2);
 90         double ans=solve(P2,cnt2);
 91         if (n==2) ans=sqrt((P1[n-1].x-P1[0].x)*(P1[n-1].x-P1[0].x)+(P1[n-1].y-P1[0].y)*(P1[n-1].y-P1[0].y)+0.0);
 92         if (n==1) ans=0;
 93         if (n>=3 && cnt2<3){//在一条直线上
 94             double Max=-99999.0,Min=999999.0;
 95             int p1,p2;
 96             if (P1[0].x!=P1[1].x){
 97             for(int i=0;i<n;i++){
 98                 if (P1[i].x<Min){
 99                     Min=P1[i].x;
100                     p1=i;
101                 }
102                 if (P1[i].x>Max){
103                     Max=P1[i].x;
104                     p2=i;
105                 }
106             }
107             }else{
108             for(int i=0;i<n;i++){
109                 if (P1[i].y<Min){
110                     Min=P1[i].y;
111                     p1=i;
112                 }
113                 if (P1[i].y>Max){
114                     Max=P1[i].y;
115                     p2=i;
116                 }
117             }
118 
119             }
120             ans=sqrt((P1[p1].x-P1[p2].x)*(P1[p1].x-P1[p2].x)+(P1[p1].y-P1[p2].y)*(P1[p1].y-P1[p2].y)+0.0);
121         }
122         printf("Case %d: %.3lf\n",cas,ans);
123    }
124     return 0;
125 }
View Code

 

 

*湖南师范大学第五届大学生计算机程序设计竞赛(AKing),布布扣,bubuko.com

*湖南师范大学第五届大学生计算机程序设计竞赛(AKing)

标签:c   style   class   blog   code   a   

原文地址:http://www.cnblogs.com/little-w/p/3779161.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!