2016 Multi-University Training Contest 2

来源:互联网 发布:成都行知小学怎么样 编辑:程序博客网 时间:2024/04/29 10:20

hdu5734 Acperience

题意:说了一大堆,求求和(wi - x * bi),使和最小,wi已知,x非负数,bi取-1或1

题解:列出二次方程,初中知识各种变就行

          最后答案是(n * 求和(wi^2) -  (求和(wi*bi))^2)

int main(){    int t;    cin>>t;    while(t--){        int n;        cin>>n;        LL x,sum1=0,sum2=0;        for(int i=0;i<n;i++){            scanf("%I64d",&x);            sum1+=(LL)x*x;            sum2+=abs(x);        }        LL ans1=(LL)n*sum1-sum2*sum2;        LL ans2=(LL)n;        //cout<<ans1<<' '<<ans2<<endl;        printf("%I64d/%I64d\n",ans1/__gcd(ans1,ans2),ans2/__gcd(ans1,ans2));    }    return 0;}

hdu5738 Eureka

题意:问有多少个点集合,点集合里面有三点共线

题解:每次选择相对最下左的点,考虑这个点上右方的点,保存斜率就好

           需要注意的是,可能有点的坐标相同

LL exp(LL a, LL b, LL c){    LL ans = 1, temp;    a = a % c;    temp = a;    while(b){        if(b&1){            ans = ans * temp % c;        }        temp = temp * temp % c;        b /= 2;    }    return ans;}struct point {    LL x, y;    bool operator<(const point&x)const{        if(this->x==x.x)            return this->y<x.y;        else            return this->x<x.x;    }}p[1010];bool cmp (point a, point b){    if(a.x == b.x)        return a.y < b.y;    else        return a.x < b.x;}map <point, LL> m1;map <point, LL> m2;int main(){    int t,n;    cin>>t;    while(t--){        cin>>n;        m1.clear();        m2.clear();        for(int i=0;i<n;i++){            cin>>p[i].x>>p[i].y;        }        sort(p,p+n,cmp);        LL ans = 0;        for(int i=0;i<n;i++){            if(m2[p[i]])                continue;            m1.clear();            for(int j=i+1;j<n;j++){                LL x = p[j].x - p[i].x;                LL y = p[j].y - p[i].y;                if(x < 0){                    x = -x;                    y = -y;                }                LL temp = __gcd(x, abs(y));                if(x!=0 && y!=0){                    if(x == 0)                        y = 1;                    if(y == 0)                        x = 1;                }                if(temp){                    x /= temp;                    y /= temp;                }                point tt;                tt.x = x;                tt.y = y;                m1[tt]++;            }            LL ll;            point pp;            pp.x=0;pp.y=0;            LL ll1 = m1[pp];            for(map<point, LL>::iterator it = m1.begin();it != m1.end();it ++){                if(it->first.x == 0 && it->first.y == 0){                    ll = exp(2, it->second + 1, mod);                    ll = ll - it->second - 2;                    ans += ll;                    ans %= mod;                }                else {                    ll = exp(2, it->second, mod);                    ll--;                    ans += (ll*(exp(2, ll1+1, mod)-1));                    ans %= mod;                }            }            m2[p[i]] = 1;        }        ans %= mod;        cout<<ans<<endl;    }    return 0;}

hdu5742 It's All In The Mind

题意:数列,有些数未知,递减,求最大(a[1] + a[2]) /  总和

题解:贪心,使a[1] + a[2]尽可能大,总和尽可能小

int main(){    int t;    cin>>t;    while(t--){        int n,m;        cin>>n>>m;        int x,y;        if(m==0 || n==2){            printf("1/1\n");            continue;        }        memset(a,-1,sizeof(a));        for(int i=0;i<m;i++){            cin>>x>>y;            a[x]=y;        }        if(a[1]==-1 && a[2]==-1){            a[1]=100;            a[2]=100;        }        else if(a[1]==-1){            a[1]=100;        }        else if(a[2]==-1){            a[2]=a[1];        }        int temp=0;        for(int i=n;i>=3;i--){            if(a[i]==-1){                a[i]=temp;            }            else {                temp=a[i];            }        }        int ans1=a[1]+a[2],ans2=0;        for(int i=1;i<=n;i++){            ans2+=a[i];        }        printf("%d/%d\n",ans1/__gcd(ans1,ans2),ans2/__gcd(ans1,ans2));    }    return 0;}

hdu5744 Keep On Movin

题意:n个字符,每个字符有ai个,可以组成x个回文串,问所有回文串中最短的最大值是多少

题解:最大化最小值,第一想法,二分

           仔细想想,其实不用二分,如果一个字符有奇数个,那么必须要在某个串的中间放一个,如果是偶数,随便添加进去就可以,找到有多少奇数个,剩下的往两边分配就好

int a[100010];int main(){    int t;    cin>>t;    while(t--){        int n;        cin>>n;        int sum=0,sum1=0;        for(int i=0;i<n;i++){            scanf("%d",&a[i]);            if(a[i]&1){                sum++;                a[i]--;            }            sum1+=a[i];        }        if(sum<=0){            cout<<sum1<<endl;        }        else {            cout<<sum1/2/sum*2+1<<endl;        }    }    return 0;}


0 0
原创粉丝点击