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


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

    A:跑得快计数程序

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

    【代码】:

     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)算法

    【代码】:

     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
    ",ans);
    56         }
    57     }
    58     return 0;
    59 }
    View Code

    D:数组求和问题

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

    【代码】:

     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
    ",cas,ans);
    23     }
    24     return 0;
    25 }
    View Code

    E:推箱子

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

    【代码】:

     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
    ",ans);
    74     }
    75     return 0;
    76 }
    View Code

    F:信封问题

    【题解】:

    【代码】:

    G:修路

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

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

    【代码】:

     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,果断超空间,其实就是异或运算性质的运用

    【代码】:

    View Code

    J:高校围墙

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

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

    【代码】:

      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
    ",cas,ans);
    123    }
    124     return 0;
    125 }
    View Code

     

  • 相关阅读:
    安装rocketmq并配置管理界面
    centos7搭建xl2tpd
    搭建fastfds+nginx
    申请SSL域名证书
    nginx返回状态码
    搭建v/2/ray和sserver
    第十一周课程总结
    第八周课程总结
    实验报告七&&课程总结
    第八周课程报告&&实验报告六
  • 原文地址:https://www.cnblogs.com/little-w/p/3779161.html
Copyright © 2020-2023  润新知