2012ACM 杭州邀请赛个别题目题解

B(HDU 4454)

Stealing a Cake
Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1795    Accepted Submission(s): 495


Problem Description
There is a big round cake on the ground. A small ant plans to steal a small piece of cake. He starts from a certain point, reaches the cake, and then carry the piece back home. He does not want to be detected, so he is going to design a shortest path to achieve his goal.

The big cake can be considered as a circle on a 2D plane. The ant’s home can be considered as a rectangle. The ant can walk through the cake. Please find out the shortest path for the poor ant.


Input
The input consists of several test cases.
The first line of each test case contains x,y, representing the coordinate of the starting point. The second line contains x, y, r. The center of the cake is point (x,y) and the radius of the cake is r. The third line contains x1,y1,x2,y2, representing the coordinates of two opposite vertices of the rectangle --- the ant's home.
All numbers in the input are real numbers range from -10000 to 10000. It is guaranteed that the cake and the ant's home don't overlap or contact, and the ant's starting point also is not inside the cake or his home, and doesn't contact with the cake or his home.
If the ant touches any part of home, then he is at home.
Input ends with a line of 0 0. There may be a blank line between two test cases.


Output
For each test case, print the shortest distance to achieve his goal. Please round the result to 2 digits after decimal point.


Sample Input
1 1
-1 1 1
0 -1 1 0
0 2
-1 1 1
0 -1 1 0
0 0


Sample Output
1.75
2.00


Source
2012 Asia Hangzhou Regional Contest


Recommend
We have carefully selected several similar problems for you:  4984 4983 4982 4981 4980 

<span style="color:#000099;">/*********************************
     author   : Grant Yuan
     time     : 2014-08-30 16:56:15
     algorithm: 三分
     source   : HDU 4454
**********************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#define PI acos(-1.0)
#define eps 1e-8
#define INF 0x7fffffff

using namespace std;
struct point
{
    double x,y;
    point(){}
    point(double _x,double _y)
    {
        x=_x;y=_y;
    }
    point operator -(const point &b)
    {
        return point(x-b.x,y-b.y);
    }
    double operator *(const point &b)
    {
        return x*b.y-y*b.x;
    }
    double operator &(const point &b)
    {
        return x*b.x+y*b.y;
    }
    void transXY(double B)
    {
        double tx=x,ty=y;
        x=tx*cos(B)-ty*sin(B);
        y=tx*sin(B)+ty*cos(B);
    }
};

struct cir
{
    double x,y;
    double r;
};
cir c;

struct line{
  point s,e;
  line(){}
  line(point _s,point _e)
       {
           s=_s;e=_e;
       }
};
line l1,l2,l3,l4;
point p0,p1,p2,p3,p4;

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

double calcdis(point p,line l)
{
      point res;
      double a,b,t;
      a=l.e.x-l.s.x;
      b=l.e.y-l.s.y;
      t=((p.x-l.s.x)*a+(p.y-l.s.y)*b)/(a*a+b*b);
      if(t>=0&&t<=1)
      {
          res.x=l.s.x+a*t;
          res.y=l.s.y+b*t;
      }
      else {
        if(dist(p,l.s)<dist(p,l.e))
            res=l.s;
        else
            res=l.e;
      }
      return dist(p,res);
}

double cal(double angle)
{
    double sum1,sum2,ans;
    double xx,yy;
    xx=c.x+c.r*cos(angle);
    yy=c.y+c.r*sin(angle);
    sum1=sqrt((xx-p0.x)*(xx-p0.x)+(yy-p0.y)*(yy-p0.y));
    point a=point(xx,yy);
    sum2=calcdis(a,l1);
    sum2=min(sum2,calcdis(a,l2));
    sum2=min(sum2,calcdis(a,l3));
    sum2=min(sum2,calcdis(a,l4));
    return sum1+sum2;
}

int main()
{
    while(1){
        scanf("%lf%lf",&p0.x,&p0.y);
        scanf("%lf%lf%lf",&c.x,&c.y,&c.r);
        scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p3.x,&p3.y);
        if(p0.x==0&&p0.y==0) break;
        p2.x=p1.x;p2.y=p3.y;p4.x=p3.x;p4.y=p1.y;
        l1=line(p1,p2);l2=line(p2,p3);l3=line(p3,p4);l4=line(p4,p1);
        double l=0,r=PI,mid,midmid,mid1,mid2;
        while(r-l>eps)
        {
            mid=(l+r)*0.5,midmid=(r+mid)*0.5;
            if(cal(mid)<cal(midmid))
                r=midmid;
            else
                l=mid;
        }
        mid1=mid;
        l=PI,r=2*PI;
        while(r-l>eps)
        {
            mid=(l+r)*0.5,midmid=(r+mid)*0.5;
            if(cal(mid)<cal(midmid))
                r=midmid;
            else
                l=mid;
        }
        mid2=mid;
       double ans;
       if(cal(mid1)<cal(mid2)) ans=cal(mid1);
       else ans=cal(mid2);
        printf("%.2lf
",ans);
    }
    return 0;
}
</span>

I(HDU4461)

The Power of Xiangqi
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1228    Accepted Submission(s): 671


Problem Description


Xiangqi is one of the most popular two-player board games in China. The game represents a battle between two armies with the goal of capturing the enemy’s “general” piece.
Now we introduce some basic rules of Xiangqi. Xiangqi is played on a 10×9 board and the pieces are placed on the intersections (points). There are two groups of pieces marked by black or red Chinese characters, belonging to the two players separately. During the game, each player in turn moves one piece from the point it occupies to another point. No two pieces can occupy the same point at the same time. A piece can be moved onto a point occupied by an enemy piece, in which case the enemy piece is "captured" and removed from the board. When the general is in danger of being captured by the enemy player on the enemy player’s next move, the enemy player is said to have "delivered a check". If the general's player can make no move to prevent the general's capture by next enemy move, the situation is called “checkmate”.
Each player has 7 kinds of pieces in this game. Their names, offense power and symbol letters are shown in the table below:





Now show you the pieces of red player and black player, you are going to find out which player has the larger total offense power. Since Ma and Pao working together can have good effect, if a player has no Ma or no Pao, or has neither, his total offense power will be decreased by one. But the total offense power can't be decreased to zero, it is at least one.


Input
The first line is an integer T ( T <= 20) meaning there are T test cases.
For each test case: The first line shows which pieces the red player has. It begins with an integer n ( 0 < n <= 16) meaning the number of pieces.
Then n letters follows, all separated by one or more blanks. Each letter is a symbol letter standing for a piece, as shown in the table above.
The second line describes the situation of the black player, in the same format as the first line.


Output
For each test case, if the red player has more offense power, then print "red". If the black player has more offense power, then print "black". If there is a tie, print "tie".


Sample Input
3
2 A B
2 A B
7 A A B C D D F
7 A A B B C C F
5 A A B B F
3 A B F


Sample Output
tie
black
red


Source
2012 Asia Hangzhou Regional Contest 

<span style="color:#000099;">/*********************************
     author   : Grant Yuan
     time     : 2014-08-30 13:39:56
     source   : HDU 4462
**********************************/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define eps 1e-8

using namespace std;

int num[]={16,7,8,1,1,2,3};
int t,n1,n2;
char a1[20],a2[20];
int main()
{
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n1);
        for(int i=0;i<n1;i++)
        {
            //scanf(" %c",a1[i]);
            getchar();
            a1[i]=getchar();
        }
        scanf("%d",&n2);
        for(int i=0;i<n2;i++)
        {
           // scanf(" %c",a2[i]);
           getchar();
           a2[i]=getchar();
        }
        int ans1=0,ans2=0;
        bool flag1=0,flag2=0;
        for(int i=0;i<n1;i++)
        {
            if(a1[i]-'A'==1) flag1=1;
            if(a1[i]-'A'==2) flag2=1;
            ans1+=num[a1[i]-'A'];
        }
        if(flag1==0||flag2==0) ans1--;
        if(ans1<1) ans1=1;
        flag1=flag2=0;
        for(int i=0;i<n2;i++)
        {
            if(a2[i]-'A'==1) flag1=1;
            if(a2[i]-'A'==2) flag2=1;
            ans2+=num[a2[i]-'A'];
        }
         if(flag1==0||flag2==0) ans2--;
        if(ans2<1) ans2=1;
        if(ans1==ans2) printf("tie
");
        else if(ans1>ans2) printf("red
");
        else printf("black
");
    }
}
</span>


 

J(HDU4462)

Scaring the Birds
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1897    Accepted Submission(s): 614


Problem Description
It’s harvest season now!
Farmer John plants a lot of corn. There are many birds living around his corn field. These birds keep stealing his corn all the time. John can't stand with that any more. He decides to put some scarecrows in the field to drive the birds away.
John's field can be considered as an N×N grid which has N×N intersections. John plants his corn on every intersection at first. But as time goes by, some corn were destroyed by rats or birds so some vacant intersections were left. Now John wants to put scarecrows on those vacant intersections and he can put at most one scarecrow on one intersection. Because of the landform and the different height of corn, every vacant intersections has a scaring range R meaning that if John put a scarecrow on it, the scarecrow can only scare the birds inside the range of manhattan distance R from the intersection.





The figure above shows a 7×7 field. Assuming that the scaring range of vacant intersection (4,2) is 2, then the corn on the marked intersections can be protected by a scarecrow put on intersection (4,2).
Now John wants to figure out at least how many scarecrows he must buy to protect all his corn.


Input
There are several test cases.
For each test case:
The first line is an integer N ( 2 <= N <= 50 ) meaning that John's field is an N×N grid.
The second line is an integer K ( 0<= K <= 10) meaning that there are K vacant intersections on which John can put a scarecrow.
The third line describes the position of K vacant intersections, in the format of r1,c1,r2,c2 …. rK,ck . (ri,ci) is the position of the i-th intersection and 1 <= r1,c1,r2,c2 …. rK,ck <= N.
The forth line gives the scaring range of all vacant intersections, in the format of R1,R2…RK and 0 <= R1,R2…RK <= 2 × N.
The input ends with N = 0.


Output
For each test case, print the minimum number of scarecrows farmer John must buy in a line. If John has no way to protect all the corn, print -1 instead.


Sample Input
4
2
2 2 3 3
1 3
4
2
2 2 3 3
1 4
0


Sample Output
-1
1


Source
2012 Asia Hangzhou Regional Contest


注:代码是队友写的

<span style="color:#000099;">#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <cctype>
#include <map>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <limits>
#include <fstream>

using namespace std;

#define mem(A, X) memset(A, X, sizeof A)
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define vi vector<int>
#define all(x) x.begin(), x.end()
#define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define sz(x) (int)((x).size())
#define sl(a) strlen(a)
#define rep(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#define Rep(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define dbg(a) cout << a << endl;
#define fi first
#define se second
typedef long long int64;
int gcd(const int64 &a, const int64 &b) {return b == 0 ? a : gcd(b, a % b);}
int64 int64pow(int64 a, int64 b){if(b == 0) return 1;int64 t = int64pow(a, b / 2);if(b % 2) return t * t * a;return t * t;}
const int inf = 1 << 30;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int MAX_N = 55;

int n, k, ans, cnt;
bool vist[MAX_N][MAX_N], point[MAX_N];

struct position {
    int x, y, range;
};

position pos[MAX_N];

bool AK()
{
    Rep(i, 1, n) {
        Rep(j, 1, n) {
            if (!vist[i][j])
                return false;
        }
    }
    return true;
}

void Gan()
{
    cnt = 0;
    int MAX_x, MIN_x, MAX_y, MIN_y;
    rep(i, 0, k) {
        if (point[i]) {
            ++cnt;
            MAX_x = pos[i].x + pos[i].range;
            MIN_x = pos[i].x - pos[i].range;
            MAX_y = pos[i].y + pos[i].range;
            MIN_y = pos[i].y - pos[i].range;

            if (MAX_x > n) MAX_x = n;
            if (MIN_x < 1) MIN_x = 1;
            if (MAX_y > n) MAX_y = n;
            if (MIN_y < 1) MIN_y = 1;

            Rep(o, MIN_x, MAX_x) {
                Rep(p, MIN_y, MAX_y) {
                    if(abs(o - pos[i].x) + abs(p - pos[i].y) <= pos[i].range)
                        vist[o][p]=1;
                }
            }
        }
    }
}

void KaiGao()
{
    ans = inf;
    rep(i, 0, 1 << k) {
        mem(vist, 0);
        mem(point, 0);
        rep(i1, 0, k) {
            vist[pos[i1].x][pos[i1].y] = true;
        }
        int t = i;
        rep(j, 0, k) {
            point[j] = t & 1;
            t >>= 1;
        }
        Gan();
        if (AK())
            ans = min(ans, cnt);
    }
}

void solve()
{
    ans = 0;
    mem(vist, 0);
    cin >> k;


    rep(i, 0, k) {
        cin >> pos[i].x >> pos[i].y;
    }
    rep(i, 0, k) {
        cin >> pos[i].range;
    }
    rep(i, 0, k) {
        vist[pos[i].x][pos[i].y] = true;
    }
    if (AK()) {
        cout << "0" << endl;
        return;
    }

    KaiGao();

    if (ans == inf)
        cout << "-1" << endl;
    else
        cout << ans << endl;

}
int main()
{
    while (cin >> n && n) {
        solve();
    }
    return 0;
}
</span>
 
K:HDU 4463
Outlets
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1866    Accepted Submission(s): 849


Problem Description
In China, foreign brand commodities are often much more expensive than abroad. The main reason is that we Chinese people tend to think foreign things are better and we are willing to pay much for them. The typical example is, on the United Airline flight, they give you Haagendazs ice cream for free, but in China, you will pay $10 to buy just a little cup.
So when we Chinese go abroad, one of our most favorite activities is shopping in outlets. Some people buy tens of famous brand shoes and bags one time. In Las Vegas, the existing outlets can't match the demand of Chinese. So they want to build a new outlets in the desert. The new outlets consists of many stores. All stores are connected by roads. They want to minimize the total road length. The owner of the outlets just hired a data mining expert, and the expert told him that Nike store and Apple store must be directly connected by a road. Now please help him figure out how to minimize the total road length under this condition. A store can be considered as a point and a road is a line segment connecting two stores.



Input
There are several test cases. For each test case: The first line is an integer N( 3 <= N <= 50) , meaning there are N stores in the outlets. These N stores are numbered from 1 to N. The second line contains two integers p and q, indicating that the No. p store is a Nike store and the No. q store is an Apple store. Then N lines follow. The i-th line describes the position of the i-th store. The store position is represented by two integers x,y( -100<= x,y <= 100) , meaning that the coordinate of the store is (x,y). These N stores are all located at different place. The input ends by N = 0.



Output
For each test case, print the minimum total road length. The result should be rounded to 2 digits after decimal point.



Sample Input
4
2 3
0 0
1 0
0 -1
1 -1
0


Sample Output
3.41


Source
2012 Asia Hangzhou Regional Contest 

<span style="color:#000099;">/*********************************
     author   : Grant Yuan
     time     : 2014-08-30 14:47:39
     algorithm: prim
     source   : HDU 4463
**********************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#define eps 1e-8
#define INF 0x7fffffff
#define MAX 57
using namespace std;

double cost[MAX][MAX];
double mincost[MAX];
bool used[MAX];
int V,n;
int p1,p2;
struct point{
 int x,y;
 };
point p[MAX];

double prim()
{
    for(int i=0;i<n;i++)
    {
        mincost[i]=INF;
        used[i]=false;
    }
    mincost[p1-1]=0;
    double res=0;
    int sum=0;
    p1=p1-1;p2=p2-1;
    while(true){
        int v=-1;
        if(sum==0){ v=p1;sum=1;}
        else if(sum==1) {v=p2;sum=2;}
        else  for(int u=0;u<n;u++)
        {
            if(!used[u]&&(v==-1||mincost[u]<mincost[v])) v=u;
        }
        if(v==-1) break;
        used[v]=true;
        res+=mincost[v];
        for(int u=0;u<n;u++)
        {
            mincost[u]=min(mincost[u],cost[v][u]);
        }
    }
        return res;
}

int main()
{
    while(1){
     scanf("%d",&n);
     if(n==0) break;
     scanf("%d%d",&p1,&p2);
     double ans;
     for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
        }
     for(int i=0;i<n;i++)
        for(int j=i;j<n;j++)
     {
          cost[i][j]=cost[j][i]=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)*1.0+(p[i].y-p[j].y)*(p[i].y-p[j].y)*1.0);
     }
     ans=prim();
     printf("%.2lf
",ans);
     }
    return 0;
}

</span>


 



 

原文地址:https://www.cnblogs.com/codeyuan/p/4254442.html