HDU武汉大学第五届E鸣杯程序设计大赛 解题报告

4 篇文章 0 订阅

首先声明这份解题报告只是小菜的一点做法,并非官方题解。


OK,下午没事干去水了下WHU的E鸣杯的比赛,题目比较简单,小菜慢慢做2个半小时也AK了~已经算很慢了,YM大仙1个半小时就AK了~Orz...


大概说下做法吧

1000:A+B problem, 汗,看到这题的时候害怕题目各位猥琐,在纠结要不要写JAVA的大数,然后刷了下Board,一群人过了,囧,保险起见开了个long long 丢上去秒了

1001:M个硬币N个海盗分钱,每个海盗分得的钱是 m/n + m%n, 暴力模拟n次输出就是咯,然后不知道这题神马情况WA了2次,不过要主要下题目的输出描述,M和N都有可能=0的,PE的估计是输漏了个空行,囧,反正我随便改改就水过了

1002:两个DFS暴力查询,DFS记录下当前分数的左边的分数和右边的分数,然后往左走就当前分数和左边的分数相加,反之亦然。从题目可以观察得出,这题分子分母的数字的              增长速度和斐波拉契数的增长速度差不多,所以没TLE的压力,写完过样例,交上去,1Y

1003:观察题目,发现Q很少小,只有5*10^4, 根据经验,直接二分答案,O(Q)的扫一遍就是了,本人写的时候加了个排序优化一下,虽然效果不是特别明显

1004:A * B ≡ 1 (mod P)(0 < A, B < P), 已知B, P,求A,这个是求逆元吧,可以P实在太小了,只有5000,for一遍,解决

1005:求不超过n的最大反素数,不解释,直接上模版,暴力构造一下就好了

1006:简单计算几何,求一个三角形最小的角,与余弦定理算就知道了。水题


题目比较简单,无压力水过了。大神们莫BS~如有说得不对的地方请多多指教。

下面上代码:

1000:

#include <iostream>
#include <cstdio>
using namespace std;
long long a, b;
int n;
int main()
{
    cin >>n;
    while (n--)
    {
          cin >>a >>b;
          cout <<a+b <<endl;
    }
    return 0;
    }

1001:

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, m;
vector<int> d;
int main()
{
    while (~scanf("%d%d", &m, &n))
    {
          d.clear();
          for (int i=0; i<n; i++)
          {
              int tmp = m/n + m%n;
              d.push_back(tmp);
              m -= tmp;              
          }
          for (int i=0; i<d.size(); i++)
          {
              if (i) printf(" ");
              printf("%d", d[i]);              
          }
          printf("\n%d\n", m);
    }    
    return 0;
    }

1002:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <functional>
#define mp make_pair
#define fi first
#define se second
using namespace std;

typedef pair<int,int> pii;
string ans2, s;
int na, nb;
pii dfs1(int idx, pii le, pii mid, pii ri)
{
    if (idx >= s.length()) return mid;
    if (s[idx] == 'L') return dfs1(idx+1, le, mp(mid.fi + le.fi, mid.se + le.se), mid);               
    else
    if (s[idx] == 'R') return dfs1(idx+1, mid, mp(mid.fi + ri.fi, mid.se + ri.se), ri);                 
    }
void dfs2(pii le, pii mid, pii ri)
{
     if (mid.fi == na && mid.se == nb) return;
     if ((1LL*na * mid.se) < (1LL*nb*mid.fi))
     {
        ans2 = ans2 + "L";
        dfs2(le, mp(mid.fi+le.fi, mid.se+le.se), mid);                 
     }
     else
     {
        ans2 = ans2 + 'R';
        dfs2(mid, mp(mid.fi+ri.fi, mid.se+ri.se), ri);   
     }
     }
int main()
{
    int T, op;
    cin >>T;
    while (T--)
    {
          cin >>op;
          if (op==1)
          {
              cin >>na >>nb;             
              ans2.clear();    
              dfs2(mp(0, 1), mp(1, 1), mp(1, 0));    
              cout <<ans2 <<endl;               
          }
          else
          {
              cin >> s;
              pii ans1 = dfs1(0, mp(0,1), mp(1, 1), mp(1, 0));
              cout <<ans1.fi <<" "<<ans1.se <<endl;
          }       
    }    
    return 0;
    }

1003:

#include <iostream>
#include <cstdio>
#include <algorithm>
#define Maxn 50050
using namespace std;

double L, V;
int n;
struct Tnode
{
       double l, r, c;
       bool operator<(const Tnode &b)const
       {
           return (l < b.l || (l==b.l && r < b.r));     
       }
       }d[Maxn];
bool check(double len)
{
     double sum = len;
     for (int i=0; i<n; i++)
     if (d[i].l <= len)
     {
         if (d[i].r <= len) sum +=  d[i].c *(d[i].r - d[i].l);
         else sum += d[i].c * (len - d[i].l);
     }
     else break;
     return sum <= V;     
     }
int main()
{
    int T;
    double lo, hi, mid;
    scanf("%d", &T);
    while (T--)
    {
          scanf("%lf%lf", &L, &V);
          scanf("%d", &n);
          for (int i=0; i<n; i++) scanf("%lf%lf%lf", &d[i].l, &d[i].r, &d[i].c);
          sort(d, d+n);
          lo = 0.0, hi=L;
          for (int i=0; i<80; i++)
          {
              mid = (lo + hi) / 2.0;
              if (check(mid)) lo = mid;
              else hi = mid;
          }
          printf("%.2f\n", mid);   
    }
    return 0;
    } 

1004:

#include <iostream>
#include <cstdio>
using namespace std;
int b, p;
int main()
{
    int T, a;
    cin >>T;
    while (T--)
    {
          cin >>b >>p;
          for (a = 1; a<p; a++)
          if ((a * b) % p == 1)
          {
                 cout <<a <<endl;
                 break;
          }
    }    
    return 0;
    }

1005:

#include <iostream>
#include <cstdio>
using namespace std;
long long pri[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int n;
long long ans, maxs; 

void dfs(long long now, long long sum, int p, long long lim)
{
     if (now > n) return;
     if (sum > maxs)
     {
        maxs = sum;
        ans = now;
     }
     else
     if (sum == maxs && ans > now) ans = now;
     if (p >= 16) return;
     long long tmp = pri[p];
     for (long long i=1; i<=lim; i++, tmp*=pri[p])
     {
         if (now*tmp > n) break;
         dfs(now*tmp, sum*(i+1), p+1, i);         
     }     
     }
int main()
{
    int T, ca=0;
    scanf("%d", &T);
    while (T--)
    {
          scanf("%d", &n);
          ans = 1;
          maxs = 1;
          dfs(1, 1, 0, 50);
          printf("Case #%d: ", ++ca);
          cout <<ans <<endl; 
    }    
    return 0;
    }

1006:

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
double xa, ya, xb, yb, xc, yc;
inline double calc(double x1, double y1, double x2, double y2)
{
       return sqrt((x1-x2)*(x1-x2) +(y1-y2)*(y1-y2));
       }
int main()
{
    while (cin >>xa >>ya >>xb >>yb >>xc >>yc)
    {
          double a = calc(xa,ya,xb,yb);
          double b = calc(xa,ya,xc,yc);
          double c = calc(xb,yb,xc,yc);
          double a1 = acos((a*a+b*b-c*c)/(2*a*b));
          double b1 = acos((a*a+c*c-b*b)/(2*a*c));
          double c1 = acos((b*b+c*c-a*a)/(2*b*c));
          double ans = min(a1, min(b1, c1));
          printf("%.6f\n", ans);
    }    
    return 0;
    }




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值