• 2018 ICPC沈阳区域赛补题


    G - Best ACMer Solves the Hardest Problem

                        Gym - 101955G 
    

    由于k都是整数,而在圆上的整数点很少,所以想到,tx^2 + ty^2 = K^2 ,
    处理出来 K 对应的所有的 tx 和 ty,那么对于(x,y),k,圆上所有的点为 (txdirx + x, tydiry + y) , dir表示方向,每一对 tx 和 ty 对应四个点; 由于tx或者 ty==0 或者 tx == ty 导致四个点有重复,所以需要去重(sort+unique或者set、map);答案用LL 存,
    这道题细节还是比较多

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e7+5;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    LL c[6005][6005];
    int xx[]={1,1,-1,-1};
    int yy[]={1,-1,-1,1};
    vector<pair<int,int> > a[N],cls;
    inline void init()
    {
        for(int i=0;i<cls.size();i++)
        {
            int x=cls[i].fi,y=cls[i].se;
            c[x][y]=0;
        }
        cls.clear();
    }
    int main()
    {
        for(int i=0;i<=6000;i++)//勾股定理,预处理所有的tx 和 ty,即能通过k知道x方向能有多少种移动方式、y能有多少种移动方式
        {
            for(int j=0;j<=6000;j++)
                if(i*i+j*j<=N-5) a[i*i+j*j].push_back(mk(i,j));
                else break;
        }
        int T=read(),test=0;
        while(T--)
        {
            int n=read(),m=read();
            for(int i=1;i<=n;i++)
            {
                int x=read(),y=read(),w=read();
                c[x][y]=w;
                cls.push_back(mk(x,y) );
            }
            LL lastans=0;
            printf("Case #%d:
    ",++test);
            while(m--)
            {
                int cmd=read(),x=read(),y=read();
                x=(x+lastans)%6000+1;
                y=(y+lastans)%6000+1;
                if(cmd==1)
                {
                    int w=read();
                    cls.push_back(mk(x,y) );
                    c[x][y]=w;
                }
                else if(cmd==2) c[x][y]=0;
                else if(cmd==3)
                {
                    set<pair<int,int> >s;//存在坐标重复,例如x、y方向移动tx、ty=0
                    或者tx=ty
                    int k=read(),w=read();
                    for(int i=0;i<a[k].size();i++)
                    {
                        pair<int,int> tmp=a[k][i];
                        for(int j=0;j<4;j++)
                        {
                            int dx=x+tmp.fi*xx[j]; // tx=tmp.fi ty=tmp.se
                            int dy=y+tmp.se*yy[j];
                            if(dx<=6000&&dx>=1&&dy>=1&&dy<=6000&&c[dx][dy]) s.insert(mk(dx,dy) );
                        }
                    }
                    for(set<pair<int,int> >::iterator it=s.begin();it!=s.end();it++)
                    {
                        pair<int,int> tmp=*it;
                        c[tmp.fi][tmp.se]+=w;
                        cls.push_back(mk(tmp.fi,tmp.se));
                    }
                }
                else
                {
                    LL ans=0;
                    int k=read();
                    set<pair<int,int> > s;
                    for(int i=0;i<a[k].size();i++)
                    {
                        pair<int,int> tmp=a[k][i];
                        //printf("tx=%d ty=%d
    ",tmp.fi,tmp.se);
                        for(int j=0;j<4;j++)
                        {
                            int dx=x+tmp.fi*xx[j];
                            int dy=y+tmp.se*yy[j];
                            if(dx<=6000&&dx>=1&&dy>=1&&dy<=6000&&c[dx][dy]) s.insert(mk(dx,dy) );//printf("dx=%d dy=%d c=%d
    ",dx,dy,c[dx][dy]);
                        }
                    }
                    for(set<pair<int,int> >::iterator it=s.begin();it!=s.end();it++)
                    {
                        pair<int,int> tmp=*it;
                        ans+=c[tmp.fi][tmp.se];
                        //printf("dx=%d dy=%d c=%d
    ",tmp.fi,tmp.se,c[tmp.fi][tmp.se]);
                    }
                    printf("%lld
    ",ans);
                    lastans=ans;
                }
            }
            init();
        }
        return 0;
    }
    
    /*
    2
    3 6
    2999 3000 1
    3001 3000 1
    3000 2999 1
    1 2999 3000 1
    4 2999 2999 1
    2 2995 2996
    3 2995 2995 1 1
    4 2995 2995 1
    4 3000 3000 1
    3 6
    2999 3000 1
    3001 3000 1
    3000 2999 1
    1 2999 3000 1
    4 2999 2999 1
    2 2995 2996
    3 2995 2995 1 1
    4 2995 2995 1
    4 3000 3000 1
    */
    
  • 相关阅读:
    简单的语句统计所有用户表尺寸大小
    CodeSmith 介绍
    Oracle Partition By 的使用
    Oracle Contact By的使用
    正则提取 html 里<input> 标记的value 值
    IOS 7 风格Checkbox
    aspose words 介绍
    大规模web 服务开发技术
    数学之美 读后感
    工作流简介--(转)
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025183.html
Copyright © 2020-2023  润新知