• 2013 CSU校队选拔赛(1) 部分题解


    A: Decimal

    Time Limit: 1 Sec   Memory Limit: 128 MB
    Submit: 99   Solved: 10
    [ Submit][ Status][ Web Board]

    Description

    任意一个分数都是有理数,对于任意一个有限小数,我们都可以表示成一个无限循环小数的形式(在其末尾添加0),对于任意一个无限循环小数都可以转化成一个分数。现在你的任务就是将任意一个无限循环小数转化成既约分数形式。所谓既约分数表示,分子和分母的最大公约数是1。

    Input

     

    有多组数据。

    每组数据一行。输入为0.a1a2a3...ak(b1b2...bm)的形式,其中a1a2a3...ak为非循环部分,(b1b2b3..bm)为循环部分。数据保证k和m不会超过8.注意长度可能为0哦!

    Output

     

    对于每组测试数据输出A/B,其中A是分子,B是分母,A,B均为整数,gcd(A, B) = 1.

    Sample Input

    0.0(714285)
    0.0(5)
    0.9(671)

    Sample Output

    1/14
    1/18
    4831/4995

    HINT http://172.16.0.11/JudgeOnline/problem.php?id=1008


                 题解:
                          对于一个分数有 0.(xxxx) = xxxx/9999 .. 0.yyy(xxxxx)=(xxxxx+yyy*9999)/9999000...注意处理没有循环节的情况..如0.xxxx为xxxx/10000...最后的分子分母记得约分
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<set>
    #define oo 1000000007
    #define ll long long
    #define MAXN 2005
    using namespace std; 
    int a;
    struct node
    {
          int d,t;
          bool operator<(node A) const
          {
                  if (A.t!=t) return A.t<ts;
                  return d<A.d;
          }
    }h;
    priority_queue<node> QA;
    int ans[MAXN];
    int main()
    { 
          int n,k,b,Q,x,i,sum,num; 
          while (~scanf("%d%d%d%d",&n,&k,&a,&b))
          {
                   while (!QA.empty()) QA.pop();
                   num=0;
                   for (i=1;i<=n;i++)
                   {
                          scanf("%d",&x);
                          if (x<=k) h.d=x,h.t=0,QA.push(h);
                               else num++; 
                   } 
                   for (int times=1;times<=205;times++)
                   { 
                          ans[times]=num;
                          if (num>0) h.d=0,h.t=times-1,QA.push(h),num--; 
                          while (!QA.empty())  
                          {
                                  h=QA.top();
                                  if (h.d+(times-h.t)*a<=k) break;
                                  QA.pop(),num++;  
                          }
                   }
                   scanf("%d",&Q);
                   while (Q--)
                   { 
                          scanf("%d",&x);
                          printf("%d
    ",ans[x]);
                   }
          }
          return 0;
    }
    

    C: Substring

    Time Limit: 4 Sec   Memory Limit: 10 MB
    Submit: 100   Solved: 11
    [ Submit][ Status][ Web Board]

    Description

    Given a string s. The length of s is smaller than 1000.You are to caculate the number of different substrings of s.

    Input

    There are multiple test cases.
    Each test case contains one line, with a string s.You may assume that s only contains
    lowercase letters. You may assume that there are only ten test cases with the length of string s is bigger than 400.

    Output

    For each test case, you are only to output one integer,  the answer.

    Sample Input

    a
    ac
    abcd

    Sample Output

    1
    3
    10

    HINT http://172.16.0.11/JudgeOnline/problem.php?id=1010

               
                 题解:
                         听说后缀数组是可以做的..我是用字典树暴力的..遇到的主要问题是空间不足.题目只给了10MB可怜的空间.无奈各种用时间换空间..才勉强过,,
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<map>
    #include<stack>
    #include<set>
    #define oo 1000000007
    #define MAXN 1005
    using namespace std;
    struct node
    {
          map<int,int> son;
    };
    map<int,node>P;
    char s[MAXN];
    vector<int> A[26];
    int main()
    {
          int len,ans,num,i,j,h,x;   
          while (~scanf("%s",s))
          {
                  len=strlen(s);     
                  for (i=0;i<26;i++) A[i].clear();
                  for (i=0;i<len;i++) 
                     A[s[i]-'a'].push_back(i);
                  ans=0;
                  for (int t=0;t<26;t++)
                  {
                        P.clear(),P[0].son.clear(),num=0;
                        for (i=A[t].size()-1;i>=0;i--) 
                        {
                                h=0;
                                for (j=A[t][i];j<len;j++)
                                { 
                                     x=s[j]-'a';
                                     if (!P[h].son[x]) 
                                         P[h].son[x]=++num,ans++,
                                         P[num].son.clear();
                                     h=P[h].son[x];
                                }
                        }
                  }
                  printf("%d
    ",ans);
          }
          return 0;
    }
    

    D: Manor

    Time Limit: 1 Sec   Memory Limit: 128 MB
    Submit: 14   Solved: 3
    [ Submit][ Status][ Web Board]

    Description

    Bob有n个正整数,他将这n个整数根据大小划分成两部分。对于小于等于k的整数放在集合A中,其余的放在集合B中。每次他从集合B中取出一个最大的值,将其变成0放入A集合中。然后将A集合中所有的元素都增加a,同时将B集合中剩余的元素都增加b,将A中大于k的元素放入B中。Bob现在想知道经过m次操作后,B集合中元素的个数。

     

    Input

    有多组测试数据。
    每组测试数据的第一行为4个整数n,k,a,b,n<=100000,k<=10^3,a,b<=100, 含义同上。接下的来的一行有n个数,表示这n个数的初始值(初始值小于等于200)。接下来的一行有一个整数q(q<=100),表示有q个询问。接下来有q行,每行一个正整数m(m<=200),表示第m次操作。

     

    Output

    对于每一个询问m,输出第m次操作前集合B中元素的个数。

     

    Sample Input

    5 100 40 20
    1000 250 300  10 25
    10
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    4 100 10 10
    105 150 25 75
    4
    1
    2
    3
    4

    Sample Output

    3
    2
    2
    3
    3
    3
    3
    3
    3
    3
    2
    1
    0
    1

    HINT http://172.16.0.11/JudgeOnline/problem.php?id=1011

      
                 题解: 
                        选拔赛的时候题目没看懂~~也有题写就没做了..其实很水的.用优先队列维护就好..只要维护小于等于k的...优先级先看入队时间.再看初值大小
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<set>
    #define oo 1000000007
    #define ll long long
    #define MAXN 2005
    using namespace std; 
    int a;
    struct node
    {
          int d,t;
          bool operator<(node A) const
          {
                  if (A.t!=t) return A.t<ts;
                  return d<A.d;
          }
    }h;
    priority_queue<node> QA;
    int ans[MAXN];
    int main()
    { 
          int n,k,b,Q,x,i,sum,num; 
          while (~scanf("%d%d%d%d",&n,&k,&a,&b))
          {
                   while (!QA.empty()) QA.pop();
                   num=0;
                   for (i=1;i<=n;i++)
                   {
                          scanf("%d",&x);
                          if (x<=k) h.d=x,h.t=0,QA.push(h);
                               else num++; 
                   } 
                   for (int times=1;times<=205;times++)
                   { 
                          ans[times]=num;
                          if (num>0) h.d=0,h.t=times-1,QA.push(h),num--; 
                          while (!QA.empty())  
                          {
                                  h=QA.top();
                                  if (h.d+(times-h.t)*a<=k) break;
                                  QA.pop(),num++;  
                          }
                   }
                   scanf("%d",&Q);
                   while (Q--)
                   { 
                          scanf("%d",&x);
                          printf("%d
    ",ans[x]);
                   }
          }
          return 0;
    }
    

    E: City Tour

    Time Limit: 1 Sec   Memory Limit: 128 MB
    Submit: 64   Solved: 12
    [ Submit][ Status][ Web Board]

    Description

    Alice想要从城市A出发到城市B,由于Alice最近比较穷(不像集训队陈兴老师是个rich second),所以只能选择做火车从A到B。不过Alice很讨厌坐火车,火车上人比较多,比较拥挤,所以Alice有很严格的要求:火车的相邻两站间的最大距离尽可能的短,这样Alice就可以在停站的时候下车休息一下。当然Alice希望整个旅途比较短。

     

    Input

    有多组测试数据。
    每组测试数据的第一行有两个整数N,M,A,B(N<=1000, M<=50000, N >=2, A,B<=N),其中N是城市的个数,M是城市间通火车的个数。
    A,B是Alice起始的城市与目的地城市,城市的标号从1开始。
    接下来的M行每行三个整数u,v,w表示从u到v和从v到u有一条铁路,距离为w, u,v<=N, w<=10000。

     

    Output

    对于每组测试数据输出满足Alice要求的从A到B的最短距离。

     

    Sample Input

    3 3 1 2
    1 2 80
    1 3 40
    2 3 50
    3 3 1 2
    1 2 90
    1 3 10
    2 3 20
    4 5 1 4
    1 2 8
    1 4 9
    1 3 10
    2 4 7
    3 4 8

    Sample Output

    90
    30
    15

    HINT http://172.16.0.11/JudgeOnline/problem.php?id=1012

     
                 题解: 
                          so easy~~二分枚举最大的边..然后用SPFA跑最短路并判断起点是否可达终点...如可达..往下二分.如果不可.往上二分..
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<set>
    #define oo 1000000007
    #define MAXN 1005
    #define MAXM 100005
    using namespace std; 
    struct node
    {
          int y,d,next;
    }line[MAXM];
    int Lnum,_next[MAXN];
    void addline(int x,int y,int d)
    {
          line[++Lnum].next=_next[x],_next[x]=Lnum,line[Lnum].y=y,line[Lnum].d=d;
    }
    queue<int> Q;
    int dis[MAXN];
    bool inqueue[MAXN];
    int SPFA(int s,int e,int M)
    { 
          while (!Q.empty()) Q.pop();
          memset(inqueue,false,sizeof(inqueue));
          memset(dis,-1,sizeof(dis));
          dis[s]=0,Q.push(s);
          while (!Q.empty())
          {
                 int h=Q.front();
                 Q.pop();
                 inqueue[h]=false;
                 for (int k=_next[h];k;k=line[k].next)
                 if (line[k].d<=M)
                 {
                          int y=line[k].y;
                          if (dis[y]==-1 || dis[y]>dis[h]+line[k].d)
                          {
                                  dis[y]=dis[h]+line[k].d;
                                  if (!inqueue[y])
                                  {
                                         inqueue[y]=true;
                                         Q.push(y);
                                  }
                          }
                 } 
          }
          return dis[e];
    }
    int main()
    {
          int i,n,m,A,B;
          freopen("input.txt","r",stdin);
          freopen("outputx.txt","w",stdout);
          while (~scanf("%d%d%d%d",&n,&m,&A,&B))
          {
                   Lnum=0,memset(_next,0,sizeof(_next));
                   while (m--)
                   {
                           int x,y,d;
                           scanf("%d%d%d",&x,&y,&d);
                           addline(x,y,d),addline(y,x,d);
                   }
                   int l=0,r=10001,mid,ans;
                   while (r-l>1)
                   {
                          mid=l+r>>1;
                          if (SPFA(A,B,mid)!=-1) r=mid;
                                    else l=mid;
                   }      
                   printf("%d
    ",SPFA(A,B,r));     
          }
          return 0;
    }
    

    I: 凹凸曼和小怪兽的故事

    Time Limit: 2 Sec   Memory Limit: 128 MB
    Submit: 7   Solved: 2
    [ Submit][ Status][ Web Board]

    Description

    世界末日来了,凹凸曼和小怪兽们开始进行最后一次较量!这次决战总共有n个凹凸曼和n个小怪兽,位置以坐标形式给出。因为是最后一次战斗,所以无论是哪一边都想要赢得第一场角逐,于是双方都想要找出最近的那一对凹凸曼和小怪兽,凹凸曼和小怪兽的速度分别为ab(单位长度每秒)。不过,凹凸曼和小怪兽的智商相信有童年的童鞋们都明白,写个程序帮他们算算最早的角逐需要多长时间开始吧,凹凸曼和小怪兽遇到了就会开始角逐,凹凸曼和小怪兽会相向而行

     

    Input

    第一行给出nab三个整数(0<n<100000);

    接下来的n行给出凹凸曼位置,每行两个整数xy(0x,y≤1000000000);

    接下来的n行给出小怪兽位置,每行两个整数xy(0x,y≤1000000000);

     

    Output

    对于每一组数据输出最短开始角逐的时间。

     

    Sample Input

    4 1 2
    0 0
    0 1
    1 0
    1 1
    2 2
    2 3
    3 2
    3 3
    4 10 0 1
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0

    Sample Output

    0.471
    0.000

    HINT  http://172.16.0.11/JudgeOnline/problem.php?id=1016


                 题解: 
                          用两个数组分别存奥特曼和小怪兽的坐标..按x大小排序..然后开始找答案.对于每个凹凸曼..先二分找到当前起x最小的小怪兽可能是多少(和当前最优值比较)..再这么扫过去..知道指向的小怪兽的x值-当前奥特曼的x值大于了当前最优解...蕴含了旋转卡壳的思想 
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<cmath>
    #include<string.h>
    #include<queue>
    #include<stack>
    #include<set>
    #define oo 2000000007
    #define MAXN 100005
    using namespace std;
    struct node
    {
          double x,y; 
          bool operator<(node a) const
          {
                   return x<a.x;
          }
    }A[MAXN],B[MAXN];
    int bearch(int n,double key)
    {
          int l=1,r=n+1,mid;
          while (r-l>1)
          {
                 mid=l+r>>1;
                 if (B[mid].x<key) l=mid;
                             else  r=mid; 
          }
          return l;
    }
    int main()
    {
          int n,i,t1,t2,v1,v2; 
          while (~scanf("%d%d%d",&n,&v1,&v2))
          {
                  for (i=1;i<=n;i++) scanf("%lf%lf",&A[i].x,&A[i].y);
                  for (i=1;i<=n;i++) scanf("%lf%lf",&B[i].x,&B[i].y); 
                  sort(A+1,A+1+n),sort(B+1,B+1+n);
                  double ans=1e+60;
                  for (t1=1;t1<=n;t1++)
                     for (t2=bearch(n,A[t1].x-ans);t2<=n && B[t2].x-A[t1].x<ans;t2++)
                        ans=min(ans,sqrt((A[t1].x-B[t2].x)*(A[t1].x-B[t2].x)+(A[t1].y-B[t2].y)*(A[t1].y-B[t2].y)));  
                  printf("%.3f
    ",ans/(v1+v2));
          }
          return 0;
    }
    




                           
  • 相关阅读:
    低功耗计算机视觉技术前沿,四大方向,追求更小、更快、更高效
    ELECTRA中文预训练模型开源,性能依旧媲美BERT
    局部敏感哈希源代码-python
    利用局部敏感哈希改进推荐系统实时性
    局部敏感哈希算法介绍
    为什么要用局部敏感哈希
    多采用panda的数据处理方式
    delphi:文件操作
    delphi:常用函数
    delphi:打印日志
  • 原文地址:https://www.cnblogs.com/riskyer/p/3275572.html
Copyright © 2020-2023  润新知