BNU Training 2015.08.17

来源:互联网 发布:进销存软件排行 编辑:程序博客网 时间:2024/05/16 12:40

        题目链接

        这套题目比较简单,为了庆祝为数不多的AK,决定把题解发一下。233....

        A. Smooth Visualization(UVALive 5870 Smooth Visualization)

        签到题一个,搞搞搞就行了。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define INF 0x3f3f3f3f#define xx first#define yy second#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn = 10000;char ans[10][maxn];char ch[maxn];void solve(){    int len = strlen(ch);    int cnt = ch[0] - '0';    cnt = 7 - cnt;    int q = ch[0] - '0';    for(int i = 0; i < 7; i ++)    {        if(cnt)        {            ans[i][0] = '*'; cnt --;        }        else ans[i][0] = '+';    }    int n = 1;    for(int i = 1; i < len; i ++)    {        q = max(q, ch[i] - '0');        int tmp = ch[i] - ch[i - 1];        if(abs(tmp) <= 1)        {            cnt = 7 - (ch[i] - '0');            for(int j = 0; j < 7; j ++)            {                if(cnt)                {                    ans[j][n] = '*'; cnt --;                }                else ans[j][n] = '+';            }            n ++;        }        else if(tmp > 0)        {            ch[i - 1] ++;            cnt = 7 - (ch[i - 1] - '0');            for(int j = 0; j < 7; j ++)            {                if(cnt)                {                    ans[j][n] = '*'; cnt --;                }                else ans[j][n] = '+';            }            n ++; i --;        }        else        {            ch[i - 1] --;            cnt = 7 - (ch[i - 1] - '0');            for(int j = 0; j < 7; j ++)            {                if(cnt)                {                    ans[j][n] = '*'; cnt --;                }                else ans[j][n] = '+';            }            n ++;  i --;        }    }    for(int i = 0; i < 7; i ++)        ans[i][n] = 0;    for(int i = 7 - q; i < 7; i ++)        puts(ans[i]);}int main(){    int T;    scanf("%d", &T);    while(T --)    {        scanf("%s", ch);        solve();    }    return 0;}
         B. Arnooks's Defensive Line(UVALive 5871 Arnooks's Defensive Line )

         因为看起来是单组数据,n=500000,cdq分治的话,算了下时间复杂度正好。于是就是一道cdq分治裸题。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn = 500100;struct Node{    char op;    int l, r, id;    void in(int i)    {        char ch[2];        scanf("%s%d%d", ch, &l, &r);        op = ch[0]; id = i;    }    bool operator < (const Node& rhs) const    {        return l < rhs.l;    }}a[maxn];int C[maxn];void add(int x, int ad){    while(x < maxn)    {        C[x] += ad;        x += x & (-x);    }}int sum(int x){    int ret = 0;    while(x)    {        ret += C[x];        x -= x & (-x);    }    return ret;}int n;vector<int> vec;int ans[maxn];void divide(int l, int r){    if(l == r) return ;    int m = (l + r) >> 1;    divide(l, m);    divide(m + 1, r);    sort(a + l, a + m + 1);    sort(a + m + 1, a + r + 1);    int cnt = 0;    for(int i = m + 1, j = l; i <= r; i ++)    {        while(j <= m && a[j].l <= a[i].l)        {            if(a[j].op != '?') add(a[j].r, 1), cnt ++;            j ++;        }        if(a[i].op == '?')        {            if(ans[a[i].id] == -1) ans[a[i].id] = 0;            ans[a[i].id] += cnt - sum(a[i].r - 1);        }    }    for(int i = m + 1, j = l; i <= r; i ++)    {        while(j <= m && a[j].l <= a[i].l)        {            if(a[j].op != '?') add(a[j].r, -1);            j ++;        }    }}void solve(){    vec.clear();    for(int i = 1; i <= n; i ++)    {        vec.push_back(a[i].r);    }    sort(vec.begin(), vec.end());    vec.erase(unique(vec.begin(), vec.end()), vec.end());    for(int i = 1; i <= n; i ++)    {        a[i].r = lower_bound(vec.begin(), vec.end(), a[i].r) - vec.begin() + 1;    }    CLR(C, 0);    CLR(ans, -1);    divide(1, n);    for(int i = 1; i <= n; i ++)        if(ans[i] != -1) printf("%d\n", ans[i]);}int main(){    scanf("%d", &n);    for(int i = 1; i <= n; i ++)        a[i].in(i);    solve();    return 0;}
        C. Equivalence(UVALive 5872 Equivalence )
        这题随便模拟就好了。做的时候uvalive崩掉了,于是连交了十来发。。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define INF 1200000000000000000ll#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;map<string,LL> mp;map<string,LL> ::iterator it;struct Exp{    vector<string> _exp;    vector<LL> xishu;    char tmp[100];    void init(){        _exp.clear();        xishu.clear();    }    void hebing(){        mp.clear();        for(int i=0;i<_exp.size();i++){            sort(_exp[i].begin(),_exp[i].end());            mp[_exp[i]]+=xishu[i];        }        init();        for(it=mp.begin();it!=mp.end();++it){            if(it->yy!=0) _exp.push_back(it->xx),xishu.push_back(it->yy);        }    }};Exp add(Exp a,Exp b){    Exp ans;ans=b;    for(int i=0;i<a._exp.size();i++){        ans._exp.push_back(a._exp[i]);        ans.xishu.push_back(a.xishu[i]);    }    ans.hebing();    return ans;}Exp sub(Exp a,Exp b){    Exp ans;ans=a;    for(int i=0;i<b._exp.size();i++){        ans._exp.push_back(b._exp[i]);        ans.xishu.push_back(-b.xishu[i]);    }    ans.hebing();    return ans;}Exp mult(Exp a,Exp b){    Exp ans;ans.init();    for(int i=0;i<a._exp.size();i++){        for(int j=0;j<b._exp.size();j++){            string tmp=a._exp[i];            if(tmp == "1") tmp = b._exp[j];            else if(b._exp[j] != "1") tmp=tmp+b._exp[j];            ans._exp.push_back(tmp);            ans.xishu.push_back(a.xishu[i]*b.xishu[j]);        }    }    ans.hebing();    return ans;}string a, b;Exp dfs(int l, int r){    Exp ret; ret.init();    if(l == r)    {        if(a[l] >= '0' && a[l] <= '9')        {            ret._exp.push_back("1");            ret.xishu.push_back(a[l] - '0');        }        else        {            string str = "";            str += a[l];            ret._exp.push_back(str);            ret.xishu.push_back(1);        }        return ret;    }    vector<Exp> vec;    string str = "";    for(int i = l; i <= r; i ++)    {        Exp tmp;        if(a[i] == '(')        {            int j = i + 1, cnt = 1;            while(j <= r)            {                if(a[j] == '(') cnt ++;                else if(a[j] == ')') cnt --;                if(cnt == 0) break;                j ++;            }            tmp = dfs(i + 1, j - 1);            i = j;        }        else        {            tmp = dfs(i, i);        }        i ++;        if(i <= r) str += a[i];        vec.push_back(tmp);    }    Exp tmp; tmp.init();    for(int i = 0; i < vec.size(); i ++)    {        tmp = vec[i];        int j = i;        while(i < str.size() && str[i] == '*')        {            tmp = mult(tmp, vec[i + 1]);            i ++;        }        if(j)        {            if(str[j - 1] == '+') ret = add(ret, tmp);            else            {                ret = sub(ret, tmp);            }        }        else ret = tmp;    }    return ret;}char ch1[10010], ch2[10010];void solve(){    gets(ch1);    gets(ch2);    int len = strlen(ch1);    a = "(";    for(int i = 0; i < len; i ++)    {        if(ch1[i] == ' ' || ch1[i] == '\t') continue;        a += ch1[i];    }    a += ")";    b = "";    int len2 = strlen(ch2);    for(int i = 0; i < len2; i ++)    {        if(ch2[i] == ' ' || ch2[i] == '\t') continue;        b += ch2[i];    }    a += "-(";    a += b;    a += ")";    for(int i = 0; i < a.size(); i ++)    {        if(a[i] >= 'A' && a[i] <= 'Z')        {            a[i] = a[i] - 'A' + 'a';        }    }    Exp ret = dfs(0, a.size() - 1);    if(ret._exp.size() == 0) puts("YES");    else puts("NO");}int main(){    int T;    scanf("%d", &T);    getchar();    while(T --)    {        solve();    }    return 0;}

        D. Tree Inspections (UVALive 5873 Tree Inspections )

        这题题意是给你n个点,然后m个横线或者竖线,如果满足在直线上站着,能垂直看到60%以上的点的话,就输出PASSED。

        横线和竖线情况相同,对于一个横线,只需要考虑他和相邻横线之间的看见的情况就可以了。可以分向上看和向下看两种情况。然后模拟一下就行了。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define INF 0x3f3f3f3f#define xx first#define yy second#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn = 100100;struct Point{    int x, y, id;    void inpt(int i)    {        scanf("%d%d", &x, &y);        id = i;    }}p[maxn];bool cmp1(Point a, Point b){    return a.x < b.x;}bool cmp2(Point a, Point b){    return a.y < b.y;}vector<int> H, V;bool vis[maxn];void solve(){    int n, m;    scanf("%d%d", &n, &m);    for(int i = 0; i < n; i ++)        p[i].inpt(i);    H.clear(); V.clear();    for(int i = 0; i < m; i ++)    {        char op[2]; int x;        scanf("%s%d", op, &x);        if(op[0] == 'H') H.push_back(x);        else V.push_back(x);    }    CLR(vis, false);    sort(H.begin(), H.end());    sort(V.begin(), V.end());    sort(p, p + n, cmp1);    map<int, int> mp;    for(int i = 0, j = 0; i < H.size(); i ++)    {        int h = H[i];        mp.clear();        while(j < n && p[j].x <= h)        {            if(mp.count(p[j].y))            {                if(p[mp[p[j].y]].x > p[j].x)                {                    mp[p[j].y] = j;                }            }            else mp[p[j].y] = j;            j ++;        }        map<int, int>::iterator it;        for(it = mp.begin(); it != mp.end(); it ++)        {            vis[p[it->yy].id] = true;        }    }    for(int i = 0, j = n - 1; i < H.size(); i ++)    {        int h = H[i];        mp.clear();        while(j >= 0 && p[j].x >= h)        {            if(mp.count(p[j].y))            {                if(p[mp[p[j].y]].x < p[j].x)                {                    mp[p[j].y] = j;                }            }            else mp[p[j].y] = j;            j --;        }        map<int, int>::iterator it;        for(it = mp.begin(); it != mp.end(); it ++)        {            vis[p[it->yy].id] = true;        }    }    sort(p, p + n, cmp2);    for(int i = 0, j = 0; i < V.size(); i ++)    {        int v = V[i];        mp.clear();        while(j < n && p[j].y <= v)        {            if(mp.count(p[j].x))            {                if(p[mp[p[j].y]].y > p[j].y)                {                    mp[p[j].x] = j;                }            }            else mp[p[j].x] = j;            j ++;        }        map<int, int>::iterator it;        for(it = mp.begin(); it != mp.end(); it ++)        {            vis[p[it->yy].id] = true;        }    }    for(int i = 0, j = n - 1; i < V.size(); i ++)    {        int v = V[i];        mp.clear();        while(j >= 0 && p[j].y >= v)        {            if(mp.count(p[j].x))            {                if(p[mp[p[j].y]].y < p[j].y)                {                    mp[p[j].x] = j;                }            }            else mp[p[j].x] = j;            j --;        }        map<int, int>::iterator it;        for(it = mp.begin(); it != mp.end(); it ++)        {            vis[p[it->yy].id] = true;        }    }    int ans = 0;    for(int i = 0; i < n; i ++)        if(vis[i]) ans ++;//, printf("%d -- %d\n", p[i].x, p[i].y);    if(ans * 10 >= n * 6) puts("PASSED");    else puts("FAILED");}int main(){    int T;    scanf("%d", &T);    while(T --)    {        solve();    }    return 0;}

       E. Social Holidaying(UVALive 5874 Social Holidaying)

       这题直接最大匹配就过了。可以的就连双向边,然后最大匹配除以二

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn=1000;int a[maxn],b[maxn];struct BPM{  int n, m;               // 左右顶点个数  vector<int> G[maxn];      // 邻接表  int left[maxn];         // left[i]为右边第i个点的匹配点编号,-1表示不存在  bool T[maxn];           // T[i]为右边第i个点是否已标记  void init(int n, int m) {    this->n = n;    this->m = m;    for(int i=0;i<=n;i++) G[i].clear();  }  bool match(int u){    for(int i = 0;i < G[u].size(); i++) {        int v=G[u][i];        if(!T[v]) {          T[v] = true;          if (left[v] == -1 || match(left[v])){            left[v] = u;            return true;          }        }    }    return false;  }  // 求最大匹配  int solve() {    memset(left, -1, sizeof(left));    int ans = 0;    for(int u = 0; u < n; u++) {      memset(T, 0, sizeof(T));      if(match(u)) ans++;    }    return ans;  }}sol;set<int> _hash;int main(){    int t;scanf("%d",&t);    while(t--){        int n,m;scanf("%d%d",&n,&m);        _hash.clear();        for(int i=0;i<n;i++) scanf("%d",&a[i]);        for(int i=0;i<m;i++){            scanf("%d",&b[i]);            _hash.insert(b[i]);        }        sol.init(n,n);        for(int i=0;i<n;i++){            for(int j=i+1;j<n;j++) if(i!=j){                if(_hash.find(a[i]+a[j])!=_hash.end()){                    sol.G[i].push_back(j);                    sol.G[j].push_back(i);                }            }        }        printf("%d\n",sol.solve()/2);    }    return 0;}

       F. Orienteering(UVALive 5875 Orienteering)
       这题发现不能背包距离,但是可以背包分数呀!于是愉快的背包出所有分数的最短距离。然后每个询问查一下就行了。查的时候随便查,二分什么的都行。暴力也能过。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn = 60600;#define MOD 1000000009double eps = 1e-8;double dp[33][maxn];double sqr(double x){    return x*x;}int sign(double x){    return (x>eps)-(x<-eps);}struct Point{    double x, y;    int s;    void inpt()    {        scanf("%lf%lf%d", &x, &y, &s);    }}p[40];double dist(Point a,Point b){    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}int Max[40];double dis[40][40];double ans[maxn];int n;void solve(){    for(int i = 1; i <= n; i ++)        p[i].inpt();    p[0].x = 0; p[0].y = 0; p[0].s = 0;    for(int i = 0; i <= n; i ++)    {        for(int j = 0; j <= n; j ++)            dis[i][j] = dist(p[i], p[j]);    }    for(int i = 0; i <= n; i ++)    {        for(int j = 0; j < maxn; j ++)            dp[i][j] = 1e30;    }    dp[0][0] = 0;    Max[0] = 0;    for(int i = 1; i <= n; i ++)    {        Max[i] = 0;        for(int j = 0; j < i; j ++)        {            for(int k = 0; k <= Max[j]; k ++)            {                dp[i][k + p[i].s] = min(dp[i][k + p[i].s], dp[j][k] + dis[i][j] - dis[j][0] + dis[i][0]);            }            Max[i] = max(Max[i], Max[j] + p[i].s);        }    }    for(int i = 0; i < maxn; i ++)        ans[i] = 1e20;    int tot = 0;    for(int i = 0; i <= n; i ++)    {        tot = max(tot, Max[i]);        for(int j = 0; j <= Max[i]; j ++)        {            ans[j] = min(ans[j], dp[i][j]);        }    }    char ch[100]; double d;    while(scanf("%s%lf", ch, &d), ch[0] != '#')    {        int out = -1;        for(int i = 0; i <= tot; i ++)        {            if(sign(d - ans[i]) >= 0)            {                out = i;            }        }        printf("%s: %d\n", ch, out);    }}int main(){    int T, cas = 1;    while(scanf("%d", &n), n)    {        printf("Race %d\n", cas ++);        solve();    }}
        G. Writings on the Wall(UVALive 5876 Writings on the Wall)

        求两个串可重叠的相连有多少种情况,扩展kmp裸题。。当s后缀和t公共前缀等于s后缀长度的时候,就是可以拼接的时候。然后。。ans++

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define INF 1200000000000000000ll#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int maxn = 100100;#define MOD 1000000007const int N = 101010;int next[N],extand[N];void getnext(char *T) // next[i]: 以第i位置开始的子串 与 T的公共前缀{    int i,length = strlen(T);    next[0] = length;    for(i = 0; i<length-1 && T[i]==T[i+1]; i++);    next[1] = i;    int a = 1;    for(int k = 2; k < length; k++)    {        int p = a+next[a]-1, L = next[k-a];        if( (k-1)+L >= p )        {            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较            next[k] = j, a = k;        }        else next[k] = L;    }}void getextand(char *S,char *T){    memset(next,0,sizeof(next));    getnext(T);    int Slen = strlen(S), Tlen = strlen(T), a = 0;    int MinLen = Slen>Tlen?Tlen:Slen;    while(a<MinLen && S[a]==T[a]) a++;    extand[0] = a, a = 0;    for(int k = 1; k < Slen; k++)    {        int p = a+extand[a]-1, L = next[k-a];        if( (k-1)+L >= p )        {            int j = (p-k+1)>0? (p-k+1) : 0;            while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++;            extand[k] = j;            a = k;        }        else extand[k] = L;    }}char s[N],t[N];void solve(){    scanf("%s%s",s,t);    getextand(s,t);    int ans = 1;    int len = strlen(s);    for(int i = 0; i < len; i++)    {        if(len - i == extand[i]) ans ++;    }    printf("%d\n", ans);}int main(){    int T;    scanf("%d", &T);    while(T --) solve();    return 0;}

       H. Robotic Traceur(UVALive 5877 Robotic Traceur)
       就是最小步数的最短路,并没有发现什么坑。。

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#define LL long long#define MP make_pair#define xx first#define yy second#define INF 0x3f3f3f3f#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const double eps=1e-8;double sqr(double x){    return x*x;}int sign(double x){    return (x>eps)-(x<-eps);}const int maxn = 1010;struct Point{    double x,y;    Point(double _x=0,double  _y=0)    {        x=_x,y=_y;    }    void input()    {        scanf("%lf%lf",&x,&y);    }} p[1024];double dist(Point a,Point b){    return sqr(a.x-b.x)+sqr(a.y-b.y);}vector<int> G[maxn];bool vis[maxn];int dp[maxn];int gao(int s, int t){    queue<int> Q;    Q.push(s);    CLR(vis, false);    CLR(dp, INF);    dp[s] = 0;    while(!Q.empty())    {        int u = Q.front(); Q.pop();        vis[u] = false;        for(int i = 0; i < G[u].size(); i ++)        {            int v = G[u][i];            if(dp[v] > dp[u] + 1)            {                dp[v] = dp[u] + 1;                if(!vis[v]) Q.push(v);                vis[v] = true;            }        }    }    return dp[t];}void solve(){    int n, s, t;    double l1, l2;    scanf("%d%d%d%lf%lf", &n, &s, &t, &l1, &l2);    l1 += l2;    for(int i = 1; i <= n; i ++)        p[i].input(), G[i].clear();    for(int i = 1; i <= n; i ++)    {        for(int j = 1; j <= n; j ++) if(i != j)        {            if(sign(dist(p[i], p[j]) - sqr(l1)) <= 0)            {                G[i].push_back(j);            }        }    }    int ret = gao(s, t);    if(ret == INF) puts("Impossible");    else printf("%d\n", ret);}
        I. Shortest Leash(UVALive 5878 Shortest Leash)

        其实我发这篇文的目的,就是说一下这道题。。

        这道题上来就被秒了,然而我感觉这道题很神啊!赛后发现大家都是用黑科技过的。。怪不得过了那么多。。个人感觉我们的思路是“杠杠的”正确。

        最后的答案,肯定是2^n种情况求出的点后排的凸包上的点。然后,假如我们已经用了前i个向量,而且求出了相应的凸包,那么,考虑第i+1个向量对当前的凸包的影响,就是把当前凸包向着i+1这个向量的两个方向拉伸了一些长度,稍微想象一下可以知道,这样的拉伸最多增加两个点啊!!于是,每次增加向量最多增加两个点。。于是,按顺序添加向量,维护凸包就可以了。。。

        加向量,排凸包,加向量,排凸包。。复杂度O(n^2*log(n))。

#include<math.h>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const double inf=1e10;const double eps=1e-8;double sqr(double x){    return x*x;}int sign(double x){    return (x>eps)-(x<-eps);}struct Point{    double x,y;    Point(double _x=0,double  _y=0){        x=_x,y=_y;    }    Point operator+(const Point &a){        return Point(x+a.x,y+a.y);    }    Point operator-(const Point &a){        return Point(x-a.x,y-a.y);    }    void input(){        scanf("%lf%lf",&x,&y);    }}p[1024],v[1024],res[1024];double mult(Point sp,Point ep,Point op){    return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);}bool operator<(const Point &l,const Point &r){    return l.y<r.y||(l.y==r.y&&l.x<r.x);}int graham(Point pnt[],int n,Point res[]){    int i,len,k=0,top=1;    sort(pnt,pnt+n);    if(n==0) return 0;res[0]=pnt[0];    if(n==1) return 1;res[1]=pnt[1];    if(n==2) return 2;res[2]=pnt[2];    for(i=2;i<n;i++){        while(top&&mult(pnt[i],res[top],res[top-1])>=0) top--;        res[++top]=pnt[i];    }    len=top;res[++top]=pnt[n-2];    for(i=n-3;i>=0;i--){        while(top!=len&&mult(pnt[i],res[top],res[top-1])>=0) top--;        res[++top]=pnt[i];    }    return top;}double dist(Point a,Point b){    return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}int main(){    int n;    while(scanf("%d",&n),n){        p[0]=Point(0,0);        int m=1;        double ans=-inf;        for(int i=0;i<n;i++){            Point tp;tp.input();            int l=0;            for(int j=0;j<m;j++){                p[m+l]=p[j]+tp;l++;                p[m+l]=p[j]-tp;l++;            }            m=graham(p,m+l,res);            for(int j=0;j<m;j++) p[j]=res[j];            for(int j=0;j<m;j++) ans=max(ans,dist(res[j],Point(0,0)));        }        printf("%.3f\n",ans);    }    return 0;}





0 0
原创粉丝点击