多第八田间学校:几何+图论出度+模拟+找到规律

HDU 4946 Area of Mushroom

这题WA了7发才过,队友做的,然后一起debug了好久。

刚開始是没排序。

然后是在同一个位置的点没有处理好。

然后把这两个问题搞定就A了。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define eps 1e-10
#define INF 0x7fffffff
#define maxn 10005
#define PI acos(-1.0)
#define seed 31//131,1313
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int x[505],y[505],v[505],vis[505];
int cmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    if(x>0)
        return 1;
    return -1;
}
inline double sqr(double x)
{
    return x*x;
}
struct point//点
{
    double x,y;
    int pos;
    int o;
    point() {}
    point(double a,double b):x(a),y(b) {}
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
    friend point operator + (const point &a,const point &b)
    {
        return point(a.x+b.x,a.y+b.y);
    }
    friend point operator - (const point &a,const point &b)
    {
        return point(a.x-b.x,a.y-b.y);
    }
    friend bool operator == (const point &a,const point &b)
    {
        return cmp(a.x-b.x)==0 &&cmp(a.y-b.y)==0;
    }
    friend point operator * (const point &a,const double &b)
    {
        return point(a.x*b,a.y*b);
    }
    friend point operator * (const double &a,const point &b)
    {
        return point(a*b.x,a*b.y);
    }
    friend point operator / (const point &a,const double &b)
    {
        return point(a.x/b,a.y/b);
    }
    double norm()
    {
        return sqrt(sqr(x)+sqr(y));
    }//到原点距离
    void out () const
    {
        printf("%.2f %.2f",x,y);
    }
} p[505];
double det (const point &a,const point &b)
{
    return a.x*b.y-a.y*b.x;
}//叉积
double dot (const point &a,const point &b)
{
    return a.x*b.x+a.y*b.y;
}//点乘
double dist (const point &a,const point &b)
{
    return (a-b).norm();
}//距离
point rotate_point(const point &p,double A)
{
    double tx=p.x,ty=p.y;
    return point (tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
}//旋转,A是弧度
struct polygon_convex
{
    vector <point> P;
    polygon_convex(int size=0)
    {
        P.resize(size);
    }
} p_c;
bool comp_less(const point &a,const point &b)
{
    return cmp(a.x-b.x)<0||cmp(a.x-b.x)==0&&cmp(a.y-b.y)<0;
}
polygon_convex convex_hull(vector <point> a)
{
    polygon_convex res(2*a.size()+5);
    sort(a.begin(),a.end(),comp_less);
    a.erase(unique(a.begin(),a.end()),a.end());
    int m=0;
    for(int i=0; i<a.size(); i++)
    {
        while(m>1 && cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<0)
            m--;
        res.P[m++]=a[i];
    }
    int k=m;
    for(int i=int(a.size())-2; i>=0; i--)
    {
        while(m>k && cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<0)
            m--;
        res.P[m++]=a[i];
    }
    res.P.resize(m);
    if(a.size()>1)
        res.P.resize(m-1);
    return res;
}
bool cmp3(point a,point b)
{
    return a.x<b.x||((a.x==b.x)&&(a.y<b.y));
}
int main()
{
    int T,tt=0;
    while(scanf("%d",&T))
    {
        tt++;
        vector<point>pp;
        pp.clear();
        memset(vis,0,sizeof(vis));
        if(T==0)
            break;
        int pos=-1;
        int max_v=0;
        for(int i=1; i<=T; i++)
        {
            scanf("%d%d%d",&x[i],&y[i],&v[i]);
            if(v[i]>max_v)
                max_v=v[i];
        }
        int top=0;
        for(int i=1; i<=T; i++)
        {
            if(v[i]==max_v)
            {
                p[top].x=(double)x[i];
                p[top].y=(double)y[i];
                p[top].pos=i;
                p[top].o=0;
                top++;
            }
        }
        printf("Case #%d: ",tt);
        if(max_v==0)
        {
            for(int i=1; i<=T; i++)
                printf("0");
            printf("
");
            continue;
        }
        sort(p,p+top,cmp3);
        for(int i=0; i<top; i++)
        {
            if((i<top-1&&(p[i].x)==(p[i+1].x)&&(p[i].y)==(p[i+1].y))||(i>0&&(p[i].x)==(p[i-1].x)&&(p[i].y)==(p[i-1].y)))
                p[i].o=1;
        }
        pp.push_back(p[0]);
        for(int i=1; i<top; i++)
        {
            if(p[i].x!=p[i-1].x||p[i].y!=p[i-1].y)
                pp.push_back(p[i]);
        }
        if(pp.size()<=3)
        {
            for(int i=0; i<pp.size(); i++)
                if(pp[i].o==0)
                    vis[pp[i].pos]=1;
        }
        else
        {
            polygon_convex ans=convex_hull(pp);
            for(int i=0; i<ans.P.size(); i++)
            {
                //cout<<ans.P[i].ok<<" "<<ans.P[i].pos<<endl;
                if(ans.P[i].o==0)
                    vis[ans.P[i].pos]=1;
            }
        }
        for(int i=1; i<=T; i++)
            printf("%d",vis[i]);
        printf("
");
    }
    return 0;
}
/*
3
2 2 3
2 2 3
2 3 3
6
1 1 3
1 -1 3
2 0 3
-1 1 3
-1 -1 3
-2 0 3
4
1 1 1
1 2 1
1 3 1
1 4 1
15
1 1 0
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
5 2 1
5 3 1
5 4 1
4 4 1
3 4 1
2 4 1
1 4 1
1 3 1
1 2 1
9
1 4 1
1 3 1
1 2 1
1 1 1
2 1 1
3 1 1
4 1 1
3 2 1
2 3 1
*/



HDU 4948 Kingdom

这题比赛的时候遗憾了。我看了这道题。然后认为挺简单的。

刚開始一看题上,想到的就是拓扑排序。然后脑子想啊想……感觉就是拓扑排序的逆序。然后发现挺水的……

由于说了要想发展某个城市的话,就必须有还有一个城市作为它发展的前提,即城市u->w这样连边,表示要想发展城市w,前提是u已经是发展过的城市了。那这种话不是非常easy嘛。

即统计出出度最多的就是第一个要发展的城市了。由于u->w这样连边能够看出算出出度最多的依次从大到小排序即可了。

哎呀。只是可惜了。由于看见没人交这题。然后也不敢把自己想的告诉队友,然后自己也没敲……然后错过进第一版的机会了哭真是被第一梯队的带错路被坑了……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define maxn 11010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
char s[500][505];
struct abc
{
    int i,out;
    bool operator<(const abc &a)const
    {
        return out>a.out;
    }
}a[501];
int main()
{
    //freopen("1.txt","r",stdin);
    int n,i,j;
    while(scanf("%d",&n)&&n)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]),a[i].i=i,a[i].out=0;
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
                if(s[i][j]=='1')
                    a[i].out++;
        sort(a,a+n);
        printf("%d",a[0].i+1);
        for(i=1;i<n;i++)
            printf(" %d",a[i].i+1);
        puts("");
    }
    return 0;
}

HDU 4951 Multiplication table

乘法表。

看每行。两个数都相等的就是0了。

然后看第一位不相等的个数,多少个不同就是哪个数了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 0x7fffffff
#define maxn 11010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int a[511][1011],vis[511];
int main()
{
    //freopen("1.txt","r",stdin);
    int n,i,j,ii=1;
    while(scanf("%d",&n)&&n)
    {
        int flag,b[512];
        for(i=0; i<n; i++)
        {
            for(j=0,flag=0; j<n; j++)
            {
                scanf("%d%d",&a[i][j<<1],&a[i][j<<1|1]);
                if(a[i][j<<1]!=a[i][j<<1|1]) flag++;
            }
            if(!flag) b[0]=i;
        }
        for(i=0;i<n;i++)
        {
            if(i==b[0]) continue;
            mem(vis,0);
            int sum=0;
            for(j=0;j<(n<<1);j+=2)
                if(!vis[a[i][j]]) sum++,vis[a[i][j]]=1;
            b[sum]=i;
        }
        printf("Case #%d: %d",ii++,b[0]);
        for(i=1;i<n;i++)
            printf(" %d",b[i]);
        puts("");
    }
    return 0;
}

HDU 4952 Number Transformation

这题规律题,输出前面100个值与倍数就会发现往后的倍数都是一样的了,倍数一样就是每次都加同样的数到最后,这种话就变成简单的乘法了。

代码中凝视的三句就是用来找规律的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define INF 10000010
#define maxn 80010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int main()
{
    ll n,m;
    int ans=1;
    while(scanf("%I64d%I64d",&n,&m)&&(n||m))
    {
        //int cnt=0;
        ll a=-1,b=-1,sum=0,i;
        int flag=0;
        for(i=2LL;i<=m;i++)
        {
            if(n%i)
            {
                b=n/i+1LL;
                n=b*i;
                //if(cnt++<100)
                //cout<<"+++ "<<n<<' '<<(int)(n/i)<<' '<<i<<endl;
                if(b==a) break;
                else a=b;
                flag=1;
            }
        }
        if(flag&&i<m)
        {
            sum=m-i;
            sum=sum*a+n;
        }
        else sum=n;
        printf("Case #%d: %I64d
",ans++,sum);
    }
    return 0;
}



原文地址:https://www.cnblogs.com/hrhguanli/p/4601602.html