hdu 2013 ACM/ICPC Asia Regional Online —— Warmup2解题报告

即hdu题库中的4716 - 4727


4716 - A Computer Graphics Problem

题意:输入一个10的倍数的数,输出一个电池的剩余电量表示图


思路:水题不解释


代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 0x1fffffff;
const int MAXN = 1000000+100;
#define eps 1e-14

string se = "*------------*";
string emp = "|............|" , full = "|------------|";

int main()
{
    int t;
    cin >>t;

    for(int i = 1 ; i <= t ; i++)
    {
        int n;
        cin >> n;
        n/=10;

        printf("Case #%d:\n",i);


        cout << se << endl;
        for(int j = 1 ; j<= 10-n ; j++)
            cout << emp << endl;
        for(int j = 1 ; j <= n ; j++)
            cout << full << endl;
        cout << se << endl;
    }

    return 0;
}


4717 The Moving Points

题意:给定一组点,每个点都朝一定向量方向在单位时间内匀速移动,求在哪一时刻任意两点的最大距离是最小的,输出时刻和距离


思路:本来以为是最近点对果断放弃,后来查了别人的题解后才知道是用三分,N值不大可以暴力求某一时刻点对的最大距离,对时间三分,直接套了个三分模板过了。


疑问:怎么证明三分一定能找到最佳时间?具体疑问在代码注释内,希望有高人解答…………


代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 0x1fffffff;
const int MAXN = 1000000+100;
#define eps 1e-14

struct point
{
    double x;
    double y;
    double vx;
    double vy;
}p[350] , curp[350];

int num;

double dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double solve(double time)
{
    for(int i = 0 ; i < num ; i++)
    {
        curp[i].x = p[i].x + p[i].vx * time;
        curp[i].y = p[i].y + p[i].vy * time;
    }

    double maxc = -1;

    for(int i = 0 ; i < num ; i++)
        for(int j = i+1 ; j < num ; j++)
            maxc = max(maxc , dis(curp[i],curp[j]));

    return maxc;
}


int main()
{
    int t;
    scanf("%d",&t);

    for(int kase = 1 ; kase <= t ; kase++)
    {

       scanf("%d",&num);


       for(int i = 0 ; i < num ; i++)
          scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].vx,&p[i].vy);

       double l=0,r=1e8,mid,midmid;

       double r1,r2;
       while(r - l > 1e-10)
       {
           mid = (l+r)/2.0;
           midmid = (mid+r)/2.0;

           r1 = solve(mid);
           r2 = solve(midmid);

           if( r1 < r2 )        //万一time>r2时有更小的最大值呢?怎么证明最佳时间一定在(l,r)内?
                r = midmid;
           else
                l = mid;
       }

       printf("Case #%d: %.2lf %.2lf\n" , kase , r , r1);
    }

    return 0;
}


4718 The LCIS on the Tree
4719 Oh My Holy FFF
4720 Naive and Silly Muggles

4721 Food and Productivity


4722 - Good Numbers

题意:我们把一个数的每个位的数加起来,如果结果能被10整除,这个数就被称为"好数",现在给定上下限,求其中的好数个数


思路:这题算是一道比较有趣的找规律题,怎么找规律呢?枚举前几个两位数,你会发现似乎是每10个数出现一次好数,然后balabala...如果这样认为并且做对了,只能说明你踩狗屎了(误?显然992 与 1009之间没有好数,而他们相差17).其实规律应该是这样的(我认为):找到一个好数,我们不停地对它加1,马上会发现其实规律是由个位数控制的:每进位一次,必定只会且肯定会出现一次好数 . 这样就好办了,我们把一个好数/10+1 (注意0也是好数),就是这个好数的位置,只要左右夹边找到两个好数就可以了


代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 0x1fffffff;
const int MAXN = 1000000+100;
#define eps 1e-14

bool calc(LL a)
{
    LL cnt=0;
    while(a)
    {
        cnt += a%10;
        a/=10;
    }

    return cnt%10;
}


int main()
{
    int t;
    scanf("%d",&t);

    for(int kase = 1 ; kase <= t ; kase++)
    {
        LL a,b;
        LL l,r;
        scanf("%I64d%I64d",&a,&b);

        for(l = a ; calc(l) ; l++);
        for(r = b ; calc(r) ; r--);

        printf("Case #%d: ",kase);

        if(l > b && r < a)
            printf("0\n");
        else
            printf("%I64d\n",r/10 - l/10+1);        //写成(r-l)/10就错了,int/int = int 的陷阱
    }
    return 0;
}


4723 How Long Do You Have to Draw
4724 If You Know This,You Must Have NO GF
4725 The Shortest Path in Nya Graph

4726 Kia's Calculation


4727 - The Number Off of FFF

题意:有一队士兵1~N,从中取出连续的一个子队,这个子队中有且仅有一个人报错数了,他会害得后面的人跟着他报错,但是仍然是+1升序的(也就是说把报错的人认为是对的,后面的人就都对了)找出这个出错者的位置。


思路:这题是大水题,但是是大坑题! 坑一:一旦一个人报错,后面的人全错,我本以为是后面的人不受影响,比如:1254567这样 ; 坑二:如果找下来没一个错,那么错的是第一个人,当时没考虑.......


代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 0x1fffffff;
const int MAXN = 1000000+100;
#define eps 1e-14

int main()
{
    int t;
    scanf("%d",&t);

    for(int kase = 1 ; kase <= t ; kase++)
    {
        int n;
        scanf("%d",&n);

        int pra,cur,pos=1;

        for(int i = 0 ; i < n ; i++)
        {
            scanf("%d",&cur);

            if(i && cur!=pra+1)
                pos=i+1;

            pra = cur;

        }

        printf("Case #%d: %d\n",kase,pos);
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值