首页 > 代码库 > 多校 2009 7

多校 2009 7

中间那几场    不太会 

B  HDU 2873 

n *m矩阵  #表示有炸弹 选这个炸弹后可以在  他上面  左边  任意位子 产生一一个炸弹  丢到1,1的自动爆炸 最后没的弄就输掉

sg函数     第一行第一列处理下 

技术分享
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>

using namespace std;

#define MAXN 10002
#define inf  1000000007
#define ll long long
#define exp 1e-8

/*
    n*m的棋盘上有若干炸弹,两人轮流引爆炸弹(1,1位置的不能选取,这个题目好像没说但样例是这个意思= =..)
引爆后会在同列的上方,同行的左方各产生一个新的炸弹(若在一个方向已经在边缘,则该方向不产生新的炸弹),没有炸弹可选的一方输,求先手胜负。
*/
char z[55][55];
int sg[55][55];
bool vis[2550];

int main()
{
        for(int i=0;i<50;i++)
        {
              sg[i][0]=i;
              sg[0][i]=i;
        }
        for(int i=1;i<50;i++)
        {
            for(int j=1;j<50;j++)
            {
                memset(vis,0,sizeof(vis));
                for(int k=0;k<i;k++)
                {
                    int a=sg[k][j];
                    for(int kk=0;kk<j;kk++)
                    {
                        int b=sg[i][kk];
                        vis[a^b]=1;
                    }
                }
                for(int k=0;;k++)
                {
                    if(vis[k]==0)
                    {
                        sg[i][j]=k;
                        break;
                    }
                }
            }
        }
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==m&&m==0)
            break;
        for(int i=0;i<n;i++)
            scanf("%s",z[i]);
        int ans=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(z[i][j]==#)
                    ans=ans^sg[i][j];
            }
        }
        if(ans==0)
            printf("Jack\n");
        else
            printf("John\n");
    }
    return 0;
}
View Code

C HDU 2874

n 个点m条边  q个查询 

然后  a b  w  无向边   权值w

问这2点能不能到达 不能  Not connected  能的话输出距离

我的空间炸了  不知道怎么弄的   感觉lca  

技术分享
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<stdlib.h>
#include<math.h>
#include<map>
#include<iterator>
#include <utility>
using namespace std;

#define MAXN 10010
#define inf  1000000007
#define ll long long

int fa[MAXN];
int vis[MAXN];
struct node
{
    int u,v,w,next;
}edge[MAXN*2],edge1[2000010];
int cnt,tot;
int head[MAXN],head1[MAXN];
int dis[MAXN];

void add(int u,int v,int w)
{
    edge[cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void add1(int u,int v,int w)
{
    edge1[tot].u=u;
    edge1[tot].v=v;
    edge1[tot].w=w;
    edge1[tot].next=head1[u];
    head1[u]=tot++;
}
int lca[1000010];
int find1(int a)
{
    if(fa[a]==a)
        return a;
    else
    {
        int b=find1(fa[a]);
        return fa[a]=b;
    }
}
void tarjan(int u,int a)
{
    vis[u]=a;
  //  printf("%d %d\n",u,a);
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!vis[v])
        {
            dis[v]=dis[u]+edge[i].w;
            tarjan(v,a);
            fa[v]=u;
        //    printf("%d %d\n",v,u);
        }
    }
    for(int i=head1[u];i!=-1;i=edge1[i].next)
    {

        int v=edge1[i].v;
        if(vis[v]==a)
        {
          //  printf("%d %d\n",v,find1(v));
            lca[edge1[i].w]=find1(v);
        }
    }
}
int main()
{
    int n,m,q;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        memset(head,-1,sizeof(head));
        cnt=0;
        tot=0;
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        memset(head1,-1,sizeof(head1));
        for(int i=1;i<=q;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add1(a,b,i);
            add1(b,a,i);
        }
        for(int i=0;i<=q;i++)
            lca[i]=inf;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dis[i]=0;
                tarjan(i,i);
            }
        }

        for(int i=0;i<tot;i+=2)
        {
            int a,b,c;
            a=edge1[i].u;
            b=edge1[i].v;
            c=edge1[i].w;
            if(lca[c]==inf)
                printf("Not connected\n");
            else
                printf("%d\n",dis[a]+dis[b]-2*dis[lca[c]]);
        }
    }
    return 0;
}
View Code

E HDU 2876

t组样例

然后  a b x y  

求d * d * |F1Q|*|F2Q|

直接算就可以      p在椭圆里   In ellipse      判断 P Q到原点的距离就可以了

技术分享
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>

using namespace std;

#define MAXN 10002
#define inf  1000000007
#define ll long long
#define exp 1e-8
double dis(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        double a,b,x1,y1;
        scanf("%lf%lf%lf%lf",&a,&b,&x1,&y1);
        if(a<b)
        {
            swap(a,b);
            swap(x1,y1);
        }
        if(x1<0)
            x1=-x1;
        if(y1<0)
            y1=-y1;
        double c=sqrt(a*a-b*b);
        double x0,y0;
        if(fabs(x1)<exp)
        {
            x0=0;
            y0=b;
        }
        else
        {
            x0=sqrt(x1*x1*a*a*b*b/(x1*x1*b*b+y1*y1*a*a));
            y0=y1/x1*x0;
        }
        if(dis(0,0,x0,y0)<=dis(0,0,x1,y1))
        {
             double ans=1/(x0*x0/(a*a*a*a)+y0*y0/(b*b*b*b))*sqrt((x0-c)*(x0-c)+y0*y0)*sqrt((x0+c)*(x0+c)+y0*y0);
            printf("%.0lf\n",ans);
        }
        else
            printf("In ellipse\n");

    }
    return 0;
}
View Code

H  HDU 2879

证明的话   不会 

结果跑下快速幂就可以了 

技术分享
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>

using namespace std;

#define MAXN 10002
#define inf  1000000007
#define ll long long

bool vis[10000010];
int prim[10000005];
ll Quick(ll a,ll b,ll c)
{
    ll ans=1;
    while(b>0)
    {
        if(b&1)
            ans=(ans*a)%c;
        b>>=1;
        a=(a*a)%c;
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(ll i=2;i*i<10000010;i++)
    {
        if(vis[i]==0)
        {
            for(ll j=i*i;j<=10000000;j=j+i)
                vis[j]=1;
        }
    }
    int cnt=0;
    for(int i=2;i<=10000000;i++)
        if(vis[i]==0)
            prim[cnt++]=i;
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        ll ans=0;
        for(int i=0;i<cnt&&prim[i]<=n;i++)
            ans=ans+n/prim[i];
        printf("%lld\n",Quick(2,ans,m));
    }
    return 0;
}
View Code

J  HDU 2881

n  m 

n*n的矩阵上面   有 m个点 时间   x y

问 最多可以走多少个点

走的花费是(x-x) +(y-y)  然后dp一下就可以了

技术分享
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>

using namespace std;

#define MAXN 10002
#define inf  1000000007
#define ll long long

struct node
{
    int a,b,c;
}z[MAXN];
bool cmp(node a,node b)
{
    return a.a<b.a;
}
int dp[MAXN];

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==m&&m==0)
            break;
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&z[i].a,&z[i].b,&z[i].c);
        sort(z+1,z+m+1,cmp);
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            dp[i]=1;
            for(int j=1;j<i;j++)
            {
                if(abs(z[i].a-z[j].a)>=(abs(z[i].b-z[j].b)+abs(z[i].c-z[j].c)))
                    dp[i]=max(dp[i],dp[j]+1);
            }
            ans=max(dp[i],ans);
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

多校 2009 7