BUPT training (5.5) 总结

The 4th Sichuan Provincial Collegiate Programming Contest

UESTC 1717

A水题0:23:12 2Y 我们都看不懂题意,Moor老老实实敲了,然后WA了,然后我YY了个题意,好吧~
题目好坑,有一句话是有误导性而且事实上没用==

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
#include <map>
#include <cmath>
using namespace std;
const int maxn = 100005;
const int inf = 1111111111;
int main()
{
    //freopen("in.txt","r",stdin);
    int cas,a[3];
    bool vis[15][15][15];
    scanf("%d",&cas);
    for(int ca = 1; ca<=cas;ca++)
    {
        scanf("%d%d%d",&a[0],&a[1],&a[2]);
        memset(vis,0,sizeof(vis));
		printf("Case #%d:\n",ca);
		sort(a,a+3);
		for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                for(int k=0;k<3;k++)
                    if(i!=j&&i!=k&&k!=j&&!vis[a[i]][a[j]][a[k]])
                    {
                        printf("%d %d %d\n",a[i],a[j],a[k]);
                        vis[a[i]][a[j]][a[k]]=1;
                    }
    }
    return 0;
}


UESTC 1710
C水题0:43:47 4Y A得好心酸的水题,而且最后是三个人都想了这道题,奠定了整场比赛不管A多少题都是最后的基调
0:24:37:TLE  while (q)没有q--,为毛测试的时候都没有发现。。。#论何其到底有多二#
0:25:28:TLE 看错数据范围了==
0:34:04:WA 想漏了一种情况
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
	int cas,n,m,q,x,ans;
	scanf("%d",&cas);
	for(int ca = 1; ca<=cas; ca++)
	{
		scanf("%d%d%d",&n,&m,&q);
		
		printf("Case #%d:\n",ca);
		while(q--)
		{
			scanf("%d",&x);
			ans = 0;
			if(n+m<x) ans =0;
			else if(x-1<=n&&x-1<=m) ans = x-1;
			else if(x-1<=n&&x-1>m) ans = m;
			else if(x-1<=m&&x-1>n) ans = n;
			else ans = n+m-x+1;
			printf("%d\n",ans);
		}
	}
	
}


UESTC 1718
K中等水题0:57:15 1Y 话说计算几何真是一道蛋蛋的忧桑嘛?
我们写不出叉积==(会好起来的……)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
#define MAXN 20
using namespace std;
long long x[4],y[4];
long long l[4];
bool check()
{
    int xx1,xx2,yy1,yy2;
    xx1=x[0]-x[1],yy1=y[0]-y[1];
    xx2=x[2]-x[1],yy2=y[2]-y[1];
    return (xx1*xx2+yy2*yy1)==0;
}
long long cal(long long a,long long b)
{
    return a*a+b*b;
}
int main()
{
    //freopen("/home/moor/Code/input.txt","r",stdin);
    int ncase;
    scanf("%d",&ncase);
    for(int h=1;h<=ncase;++h)
    {
        for(int i=0;i<4;++i)
            scanf("%lld%lld",&x[i],&y[i]);
        for(int i=0;i<4;++i)
            l[i]=cal(x[i]-x[(i+1)%4],y[i]-y[(i+1)%4]);
        printf("Case #%d: ",h);
        if(l[0]==l[2]&&l[1]==l[3])
        {
            if(l[0]==l[1])
            {
                if(check())
                    printf("Square\n");
                else    printf("Diamond\n");
            }
            else    if(check())
                printf("Rectangle\n");
            else    printf("Parallelogram\n");
        }
        else    printf("Others\n");
    }
    return 0;
}
UESTC 1717
JLCA3:31:00 3Y
我一开始的想法就是错的,然后骗着Moor屁颠屁颠地去敲了,
过了好久,敲完B才发现其本质
但是第一炮TLE了,找得我眼睛都瞎了,
两个邻接表加边的时候用的是同一个边计数器
其实就是增加一条边问图中任意两点间最短路有没有变化  
 题目给的是图是树都可以做
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 600010
using namespace std;
int ans[MAXN];
struct _tree
{
    int he[MAXN],to[MAXN],nex[MAXN],l[MAXN],top;
    int ahe[MAXN],ato[MAXN],anex[MAXN],al[MAXN],atop;
    int fat[MAXN];
    int toroot[MAXN];
    bool vi[MAXN];
    void add(int u,int v,int c)
    {
        to[top]=v;
        nex[top]=he[u];
        l[top]=c;
        he[u]=top++;
    }
    int findfa(int h)
    {
        if(h!=fat[h])
            fat[h]=findfa(fat[h]);
        return fat[h];
    }
    void mul(int a,int b)
    {
        a=findfa(a),b=findfa(b);
        if(a==b)    return ;
        fat[b]=a;
    }
    void init()
    {
        top=0;
        atop=0;
        for(int i=0;i<MAXN;++i)
            fat[i]=i;
        memset(he,-1,sizeof(he));
        memset(ahe,-1,sizeof(ahe));
        memset(vi,0,sizeof(vi));
    }
    void dfs(int h,int fa,int len)
    {
        toroot[h]=len;
        for(int i=he[h];i!=-1;i=nex[i])
            if(to[i]!=fa)
                dfs(to[i],h,len+l[i]);
    }
    void aadd(int u,int v,int c)
    {
        ato[atop]=v;
        anex[atop]=ahe[u];
        al[atop]=c;
        ahe[u]=atop++;
    }
    void tarjan(int h,int fa)
    {
        for(int i=he[h];i!=-1;i=nex[i])
            if(to[i]!=fa)
            {
                tarjan(to[i],h);
                fat[to[i]]=h;
            }
        for(int i=ahe[h];i!=-1;i=anex[i])
            if(vi[ato[i]])
                ans[al[i]]=(toroot[h]+toroot[ato[i]]-2*toroot[findfa(ato[i])]);
        vi[h]=1;
    }
}tr;
int query[100010][2];
int main()
{
    //freopen("/home/moor/Code/input.txt","r",stdin);
    int ncase,n,q;
    int a,b,c,x,y,z;
    scanf("%d",&ncase);
    for(int h=1;h<=ncase;++h)
    {
        scanf("%d%d",&n,&q);
        tr.init();
        for(int i=0;i<n-1;++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            tr.add(a,b,c);
            tr.add(b,a,c);
        }
        scanf("%d%d%d",&x,&y,&z);
        memset(ans,0,sizeof(ans));
        tr.dfs(1,-1,0);
        for(int i=0;i<q;++i)
        {
            scanf("%d%d",&a,&b);
            query[i][0]=a,query[i][1]=b;
            tr.aadd(a,b,i);
            tr.aadd(b,a,i);
        }
        for(int i=0;i<n;++i)
            tr.aadd(i+1,x,i+q),
            tr.aadd(x,i+1,i+q);
        for(int i=0;i<n;++i)
            tr.aadd(i+1,y,i+q+n),
            tr.aadd(y,i+1,i+q+n);
        printf("Case #%d:\n",h);
        tr.tarjan(1,-1);
        for(int i=0;i<q;++i)
        {
            int tmp;
            a=query[i][1]-1+q;
            b=query[i][0]+n-1+q;
            tmp=ans[a]+ans[b]+z;

            a=query[i][0]-1+q;
            b=query[i][1]+n-1+q;
            tmp=min(tmp,ans[a]+ans[b]+z);
            ans[i]-=tmp;
        }
        for(int i=0;i<q;++i)
            printf("%d\n",ans[i]>0?ans[i]:0);
    }
    return 0;
}


UESTC 1709
B想法题2:51:06 4Y
如果没记错的话,其实前面三炮都是在一句话上错了 
 long long s=(long long)n*(n+1)/2
感觉思想很经典,牵扯到位运算的很多题都是一位一位的看

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 60010
using namespace std;
int sum[32][MAXN],num[MAXN],n;
bool whi[32][MAXN];
double a[3];
void caland(int h)
{
    long long cnt=0,prev=1;
    long long ss=(long long)(n+1)*n/2;
    for(int i=1;i<=n;++i)
    {
        if(whi[h][i]==0)    prev=-1;
        else
        {
            if(prev==-1)    prev=i;
            cnt+=i-prev+1;
        }
    }
    a[0]+=(double)cnt/ss*(1<<h);
}
void calor(int h)
{
    long long cnt=0,prev=1;
    long long ss=(long long)(n+1)*n/2;
    for(int i=1;i<=n;++i)
    {
        if(whi[h][i]==1)    prev=-1;
        else
        {
            if(prev==-1)    prev=i;
            cnt+=i-prev+1;
        }
    }
    a[1]+=(double)(ss-cnt)/ss*(1<<h);
}
void calxor(int h)
{
    long long cnt=0,odd=0,even=1;
    long long ss=(long long)(n+1)*n/2;
    for(int i=1;i<=n;++i)
    {
        if(sum[h][i]&1)
            cnt+=even;
        else    cnt+=odd;
        if(sum[h][i]&1) ++odd;
        else    ++even;
    }
    a[2]+=(double)cnt/ss*(1<<h);
}
int main()
{
    //freopen("/home/moor/Code/output.txt","r",stdin);
    int ncase;
    scanf("%d",&ncase);
    for(int h=1;h<=ncase;++h)
    {
        memset(sum,0,sizeof(sum));
        memset(whi,0,sizeof(whi));
        for(int i=0;i<3;++i)
            a[i]=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
            scanf("%d",&num[i]);
        for(int i=0,j=1;i<31;++i,j<<=1)
            for(int k=1;k<=n;++k)
                sum[i][k]=sum[i][k-1]+((num[k]&j)==j),whi[i][k]=(num[k]&j)==j;

        for(int i=0;i<31;++i)
        {
            caland(i);
            calor(i);
            calxor(i);
        }
        printf("Case #%d: %.6f %.6f %.6f\n",h,a[0],a[1],a[2]);
    }
}


UESTC 1711
D贪心听了Moor的想法,感觉这道题不难的样子,
但是过的人好少的样子,一定是黎神太强了
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <set>
#define MAXN 600010
#define INF 1000000000
using namespace std;
long long num[MAXN];
int pos;
long long x[MAXN];
long long add(int h)
{
    long long cnt=0;
    num[h]+=x[h];
    for(int i=h;i<pos;++i)
        if(num[i]>1)
            num[i+1]+=num[i]/2,
            num[i]=num[i]&1;
        else    break;
    if(num[pos]>0)
        --num[pos];
    else    return x[h];
    for(int i=pos;i>=h;--i)
        cnt=cnt*2+num[i],
        num[i]=0;
    pos=-1;
    return x[h]-cnt;
}
int main()
{
    //freopen("/home/moor/Code/input.txt","r",stdin);
    int ncase,n,a,tmp;
    scanf("%d",&ncase);
    for(int h=1;h<=ncase;++h)
    {
        scanf("%d",&n);
        memset(x,0,sizeof(x));
        memset(num,0,sizeof(num));
        for(int i=0;i<n;++i)
        {
            scanf("%d%d",&a,&tmp);
            x[a]+=tmp;
        }
        pos=-1;
        for(int i=MAXN-1;i>=0;--i)
            if(x[i])
            {
                if(pos!=-1)
                    x[i]-=add(i);
                if(pos==-1)
                {
                    if(x[i]&1)
                        pos=i;
                }
            }
        printf("Case #%d: ",h);
        if(pos==-1)
            printf("0\n");
        else
        {
            for(int i=0;i<=pos;++i)
                num[i]=!num[i];
            ++num[0];
            ++num[pos];
            for(int i=0;i<=pos;++i)
                if(num[i]>1)
                    num[i+1]+=num[i]/2,
                    num[i]=num[i]&1;
            for(int i=pos;i>=0;--i)
                if(num[i]!=0)
                {
                    for(;i>=0;--i)
                        printf("%d",(int)num[i]);
                    printf("\n");
                    break;
                }
        }
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值